在 Groovy/Grails 中不安全地使用用户提供的 GString:s

发布于 2024-07-16 09:52:32 字数 1335 浏览 6 评论 0原文

Groovy 中的 GString 概念非常强大(请参阅 http://groovy.codehaus.org/Strings+和+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 严格控制过滤方法。

The GString concept in Groovy is pretty powerful (see http://groovy.codehaus.org/Strings+and+GString).

GStrings let you do things like:

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

I'm trying to figure out if using Groovy GString:s can introduce security problems in your code similar to SQL injection attacks.

In the example above the code was written by the author of the program, so the execution of the System.exit(-1) command cannot be seen as a security flaw as it was the stated intent of the author.

Let's say I'm writing a Grails web-app, where user input is taken from form fields (reading POST/GET params) and database tables (using GORM). Let's assume that an attacker controls both what's sent as POST/GET requests to the server and what's in the database.

The code in my app looks like this:

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

Is there any way an attacker can execute code in the above scenario? Why? Why not? My initial hypothesis is that GString usage is always safe. Please feel free to prove me wrong. Please be as concrete as possible.

Update #1: To keep the discussion focused, please disregard any HTML-XSS problems in the code since this question is about code-execution on the server-side, not on the client-side.

Update #2: Some people have pointed out that it is "generally a good idea to filter out unwanted strings". While filtering out "potentially bad characters" might certainly save you from some classes of security problems, it would be even better to write code that would be safe even without filtering. You can compare it with usage of PreparedStatements in the Java JDBC API - correct usage of PreparedStatements is guaranteed to save you from certain classes of injection attacks. Filtering your SQL input will probably give you the same result, but using PreparedStatements strictly dominates the filtering approach IMHO.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

像极了他 2024-07-23 09:52:32

不会,您不会遇到 GString 机制引入的任何问题,因为 GString 的形成是一种“编译时”现象。 虽然它们的值可以在运行时确定(和更改),但它们的形式却不是。

另一种看待它的方式:使用 GString 可以做的任何事情都可以通过闭包和字符串连接来完成,具有完全相同的语义; GString 只是语法糖。 除非你担心闭包(或者,天堂不允许,字符串连接),否则你不应该担心 GStrings。

No, you won't have any new problems introduced by the GString mechanism, because the formation of GStrings is a "compile time" phenomenon. While their value may be determined (and changed) at run time their form is not.

Another way of looking at it: anything you can do with GStrings could be done with a closure and string concatenation, with exactly the same semantics; GStrings are just syntactic sugar. Unless you are worried about closures (or, heaven forbid, string concatenation) you shouldn't worry about GStrings.

迷迭香的记忆 2024-07-23 09:52:32

对于给定的代码示例,不存在安全问题。 str1 和 str2 只是调用它们的 toString 方法,GString 上的默认 toString 方法不存在安全漏洞。

除非您(程序作者)已经为“somePropertyFieldControlledByTheAttacker”定义了 getter 来实际对值的内容进行评估,否则它是安全的。

发生安全漏洞的唯一方法是程序作者添加一个安全漏洞。

With the given code sample, there isn't a a security issue. str1 and str2 simply have their toString methods called and there is not a security hole with the default toString methods on GStrings.

Unless you, the programs author, had defined the getter for "somePropertyFieldControlledByTheAttacker" to actualy do an eval on the content of the value, it's safe.

The only way a security hole would happen is if the programs author adds one.

忘羡 2024-07-23 09:52:32

再想一想,看来你的使用很好,因为你只是评估你定义为变量的局部变量,但字符串仍然需要删除特殊字符,但不是像“System.exit(-1)”这样的东西,因为除非 ${} 在字符串中围绕它,否则它将自始至终将其视为字符串。

最佳实践似乎是从字符串中删除所有特殊字符,例如“${}”,因为您不必在代码中使用它们就容易受到它们的攻击。<​​/strong>

但是,如果它从不以嵌套方式评估字符串,你没问题,所以我不能 100% 确定。

On second thought, It appears your use is fine since you simply eval the local variables that you define as a variable, but the string still has to be scrubbed of special character, but not things like "System.exit(-1)" because it will treat this as a string the whole way through unless ${} is around it in the string.

It would appear best practice would be to remove all special characters from strings, like "${}" because you don't have to use them in your code to be vulnerable to them.

But, if it never evals the string in a nested fashion you are fine, so I am not 100% sure.

爱*していゐ 2024-07-23 09:52:32

上面的代码中可能存在跨站点脚本漏洞 - 确保调用 .encodeAsHTML(),否则坏人可能会惹恼你。

you may have a cross-site scripting vulnerability in the above code- make sure you call .encodeAsHTML(), or a bad guy can mess with ya.

梦回梦里 2024-07-23 09:52:32

我相当确定作为参数传入的对象(在控制器中)是纯字符串,因此它们不会在运行时进行评估(就像 GString 那样)。 此外,我做了一些实验,似乎要将它们转换为 GString,您需要做一些相当粗糙的工作。 这是可行的,但需要大量的杂耍。

简而言之,这可能不是一个安全漏洞。

删除特殊字符仍然是一个非常非常非常好的主意,至少在不需要它们的字符串中......尽管确定这是“留给读者的练习”。 但只要您意识到所有用户生成的数据(从网络或数据库中提取的数据)都是可疑的,您就会安全得多。

I'm fairly certain that the objects passed in as params (in the Controller) are plain strings, and so they don't get evaluated at runtime (as GStrings do). Furthermore, I did a bit of experimentation, and it seems that to turn these into GStrings you need to do some pretty gnarly work. It's doable, but requires a lot of juggling.

In short, it's probably not a security hole.

It's still a really, really, really good idea to strip out special characters, at least in strings where they aren't needed... although determining this is 'left as an exercise to the reader'. But as long as you're conscious that all user-generated data (data pulled from the web or from the DB) is suspect, you'll be a lot safer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文