Небезопасное использование пользовательских GString: s в Groovy / Grails - PullRequest
4 голосов
/ 22 марта 2009

Концепция GString в Groovy довольно мощная (см. http://groovy.codehaus.org/Strings+and+GString).

GStrings позволяют вам делать такие вещи, как:

world = "World"
println "Hello ${world}"
# Output: Hello World
println "1+2 = ${1+2}"
# Output: 1+2 = 3
println "${System.exit(-1)}"
# Program terminated

Я пытаюсь выяснить, может ли использование Groovy GString: s создать проблемы с безопасностью в вашем коде, подобные атакам с использованием SQL-инъекций.

В приведенном выше примере код был написан автором программы, поэтому выполнение команды System.exit (-1) не может рассматриваться как недостаток безопасности, поскольку это было заявленным намерением автора.

Допустим, я пишу веб-приложение Grails, где пользовательский ввод берется из полей формы (чтение параметров POST / GET) и таблиц базы данных (с использованием GORM). Предположим, что злоумышленник контролирует как то, что отправляется на сервер в виде запросов POST / GET, так и то, что находится в базе данных.

Код в моем приложении выглядит так:

def str1 = params.someParameterControlledByTheAttacker
def str2 = SomeGORMPersistedObject.get(1).somePropertyFieldControlledByTheAttacker
render "Hello! Here is some text: ${str1} and ${str2}"

Есть ли способ, которым злоумышленник может выполнить код в приведенном выше сценарии? Зачем? Почему бы и нет? Моя первоначальная гипотеза заключается в том, что использование GString всегда безопасно. Пожалуйста, не стесняйтесь доказать, что я неправ. Пожалуйста, будьте как можно конкретнее.

Обновление № 1: Чтобы сфокусировать обсуждение, пожалуйста, не обращайте внимания на любые проблемы HTML-XSS в коде, так как этот вопрос касается выполнения кода на стороне сервера, а не на стороне клиента.

Обновление № 2: Некоторые люди отмечают, что "обычно неплохо отфильтровывать нежелательные строки". Хотя отфильтровывание «потенциально плохих символов» может, безусловно, избавить вас от некоторых проблем с безопасностью, было бы еще лучше написать код, который был бы безопасным даже без фильтрации. Вы можете сравнить его с использованием PreparedStatements в Java JDBC API - правильное использование PreparedStatements гарантировано , чтобы уберечь вас от определенных классов атак внедрения. Фильтрация вашего ввода SQL, вероятно, даст вам тот же результат, но использование PreparedStatements строго доминирует в подходе фильтрации IMHO.

Ответы [ 5 ]

3 голосов
/ 07 апреля 2009

Нет, у вас не будет никаких новых проблем, введенных механизмом GString, потому что формирование GStrings является феноменом "времени компиляции". Хотя их значение может быть определено (и изменено) во время выполнения, их форма не является.

Другой способ взглянуть на это: все, что вы можете сделать с помощью GStrings, можно сделать с помощью замыкания и конкатенации строк с точно такой же семантикой; GS строки - просто синтаксический сахар. Если вы не беспокоитесь о замыканиях (или, не дай бог, о конкатенации строк), вам не следует беспокоиться о GStrings.

0 голосов
/ 01 апреля 2009

у вас может быть уязвимость межсайтового скриптинга в приведенном выше коде - убедитесь, что вы вызываете .encodeAsHTML (), иначе плохой парень может связываться с вами.

0 голосов
/ 31 марта 2009

Если подумать: кажется, что вы используете нормально, так как вы просто оцениваете локальные переменные, которые вы определили как переменную, но строку по-прежнему нужно очищать специальным символом, а не такими вещами, как "System.exit (-1 ) "потому что он будет обрабатывать это как строку в течение всего пути, если $ {} не находится вокруг него в строке.

Казалось бы, лучшая практика - удалять все специальные символы из строк, например "$ {}", потому что вам не нужно использовать их в своем коде, чтобы быть уязвимыми для них.

Но, если она никогда не уклоняется от вложенной строки, у вас все хорошо, поэтому я не уверен на 100%.

0 голосов
/ 01 апреля 2009

Я вполне уверен, что объекты, передаваемые как параметры (в Контроллере), являются простыми строками, и поэтому они не оцениваются во время выполнения (как GStrings). Кроме того, я немного поэкспериментировал, и кажется, что для того, чтобы превратить их в GStrings, вам нужно сделать довольно скучную работу. Это выполнимо, но требует много подтасовок.

Короче говоря, это, вероятно, не дыра в безопасности.

Это все-таки действительно хорошая идея - вырезать специальные символы, по крайней мере, в строках, где они не нужны ... хотя определение этого «оставлено читателю как упражнение». Но если вы осознаете, что все данные, сгенерированные пользователем (данные, извлеченные из Интернета или из БД), являются подозрительными, вы будете намного безопаснее.

0 голосов
/ 22 марта 2009

В данном примере кода проблемы безопасности нет. str1 и str2 просто вызывают свои методы toString, и в GStrings нет дыры в безопасности с методами toString по умолчанию.

Если вы, автор программ, не определили метод получения для "somePropertyFieldControlledByTheAttacker", чтобы реально оценить содержимое значения, это безопасно.

Единственный способ сделать дыру в безопасности - добавить ее к автору программ.

...