Groovy 中的 GString 概念非常强大(参见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 Web 应用程序,其中用户输入来自表单字段(读取 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:有人指出“过滤掉不需要的字符串通常是个好主意”。虽然过滤掉“潜在的坏字符”肯定可以让您避免某些类别的安全问题,但编写即使没有过滤也安全的代码会更好。您可以将其与 Java JDBC API 中 PreparedStatements 的用法进行比较——正确使用 PreparedStatements 可以保证您免受某些类型的注入攻击。过滤您的 SQL 输入可能会给您相同的结果,但使用 PreparedStatements 严格控制过滤方法恕我直言。