Groovy / Grails:有没有办法让.evaluate()完全安全?

时间:2011-07-21 22:56:46

标签: security grails groovy evaluate groovyshell

我有一种情况需要确定一个对象“骑”另一个对象的可能性。车辆的规则非常令人困惑,我希望能够在不重新启动或重新编译项目的情况下更改它们。

这种方法很有效,但基本上让我的安全朋友感到厌烦并说方言:

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]
}

因此,如果我想添加一条规则,即如果你的“东西”是“peggy”或“华夫饼”并且你的someNumber大于你的另一个号码,那么你只能获得某辆车的资格,我所要做的就是:< / p>

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

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

然后我只需要制作一个VehicleConstraintLinker来连接它并瞧。

我的问题是:有没有办法限制GroovyShell可以做什么?我可以让它无法更改任何文件,全局变量或数据库数据吗?这还够吗?

1 个答案:

答案 0 :(得分:2)

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

provide security sandbox for executing scripts尝试使用GroovyClassLoader提供沙盒。

Sandboxing Java / Groovy / Freemarker Code - Preventing execution of specific methods讨论了沙箱groovy的方法,但没有具体讨论evaluate边界。

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

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