Groovy / Grails: есть ли способ сделать .evaluate () вообще безопасным? - PullRequest
1 голос
/ 22 июля 2011

У меня есть ситуация, когда мне нужно определить право на то, чтобы один объект «ездил» на другом. Правила для транспортных средств сильно сбивают с толку, и я хотел бы изменить их, не перезапуская и не перекомпилируя мой проект.

Это работает, но в основном заставляет моих друзей по безопасности судорожно говорить и говорить на языках:

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

Так что, если я хочу добавить правило, согласно которому вы имеете право только на определенное транспортное средство, если ваш «материал» «пегги» или «вафли», а ваш someNumber больше, чем ваш anotherNumber, все, что мне нужно сделать, это:

Создайте новый ConstraintByClosure с humanReadable = "peggy waffle some #>" (это объяснение, понятное человеку), а затем добавьте эту строку как closureText

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

Тогда я просто создаю привязку VehicleConstraintLinker, чтобы связать ее и вуаля.

Мой вопрос таков: есть ли способ ограничить то, что может делать GroovyShell? Могу ли я сделать невозможным изменение каких-либо файлов, глобальных переменных или данных базы данных? Достаточно ли этого?

1 Ответ

2 голосов
/ 22 июля 2011

Имейте в виду, что отказа в доступе к java.io и java.lang.Runtime в их различных проявлениях недостаточно.Существует много базовых библиотек с полным набором полномочий, которые злоумышленник может попытаться использовать, поэтому вам нужно либо внести в белый список символы, к которым может обращаться ненадежный скрипт (песочница или безопасность на основе возможностей), либо ограничить все, что может в JVMделать (через Java SecurityManager).В противном случае вы уязвимы для запутанных депутатских атак .

. Предоставьте изолированную программную среду безопасности для выполнения сценариев. пытается работать с GroovyClassLoader для обеспечения изолированной среды.

Песочница Java / Groovy / код Freemarker - Предотвращение выполнения определенных методов обсуждает способы песочницы groovy, но не специально на evaluate границах.

Groovy Scripts и JVM Security рассказывает о песочнице, заводные скрипты.Я не большой поклонник политик безопасности JVM, так как установка менеджера безопасности может повлиять на множество других вещей в JVM, но он обеспечивает способ перехвата доступа к файлам и вещам во время выполнения.

Я не знаю, какая из первых двух схем подвергалась широко распространенным атакам, поэтому я бы опасался их развертывания без тщательного анализа атак.Менеджер безопасности JVM подвергся широко распространенной атаке в браузере и претерпел множество сбоев.Это может быть хорошая глубокая защита, поэтому я бы не стал полагаться на нее как на единственную линию защиты в отношении чего-либо ценного.

...