2

我有一种情况,我需要确定一个对象是否有资格“骑”另一个对象。车辆的规则非常混乱,我希望能够在不重新启动或重新编译我的项目的情况下更改它们。

这行得通,但基本上让我的安全朋友抽搐并说方言:

class SweetRider{
  String stuff
  BigDecimal someNumber
  BigDecimal anotherNumber
}

class SweetVehicle{
  static hasMany=[constraintLinkers:VehicleConstraintLinker]
  String vehicleName
  Boolean canIRideIt(SweetRider checkRider){
    def checkList = VehicleConstraintLinker.findAllByVehicle(this)
    checkList.each{
      def theClosureObject = it.closureConstraint
      def iThinkINeedAShell = new GroovyShell()
      def checkerThing = iThinkINeedAShell.evaluate(theClosureObject.closureText)
      def result = checkerThing(checkRider)
      return result
    }
  }
}

class VehicleConstraintLinker{
  static belongsTo = [closureConstraint:ConstraintByClosure, vehicle:SweetVehicle]
}

class ConstraintByClosure{
  String humanReadable
  String closureText
  static hasMany = [vehicleLinkers:VehicleConstraintLinker]
}

因此,如果我想添加规则,如果您的“stuff”是“peggy”或“waffles”并且您的 someNumber 大于您的 anotherNumber,那么您只有资格使用特定车辆,我所要做的就是:

使用 humanReadable = "peggy waffle some#>" (这是人类可读的解释)创建一个新的 ConstraintByClosure,然后将此字符串添加为closureText

{
   checkRider->if(
     ["peggy","waffles"].contains(checkRider.stuff) &&
     checkRider.someNumber > checkRider.anotherNumber ) {
     return true  
   } 
   else { 
      return false
   }
}

然后我只是制作了一个 VehicleConstraintLinker 来链接它,瞧。

我的问题是:有什么方法可以限制 GroovyShell 的功能吗?我可以让它无法更改任何文件、全局变量或数据库数据吗?这足够了吗?

4

1 回答 1

2

请注意,以各种形式拒绝访问java.iojava.lang.Runtime不够的。有许多核心库具有大量权限,恶意编码人员可以尝试利用,因此您需要将不受信任的脚本可以访问的符号列入白名单(沙盒或基于能力的安全性)或限制 JVM 中的任何内容可以做(通过Java SecurityManager)。否则你很容易受到迷惑副手的攻击

为执行脚本提供安全沙箱尝试与GroovyClassLoader提供沙箱一起工作。

沙盒 Java / Groovy / Freemarker 代码 - 防止执行特定方法讨论了沙盒 groovy 的方法,但不是专门针对evaluate边界。

Groovy Scripts and JVM Security讨论了沙盒化 groovy 脚本。我不是 JVM 安全策略的忠实拥护者,因为安装安全管理器会影响 JVM 中的许多其他内容,但它确实提供了一种拦截对文件和运行时内容的访问的方法。

我不知道前两个方案中的任何一个都受到了广泛的攻击,所以如果没有彻底的攻击审查,我会对部署它们持谨慎态度。JVM 安全管理器在浏览器中受到了广泛的攻击,并遭受了许多失败。它可以是一个很好的纵深防御,所以我不会依赖它作为任何珍贵事物的唯一防线。

于 2011-07-22T00:31:39.707 回答