在 Ruby 中,有什么方法可以通过插值将数据添加到字符串中来终止字符串?例如:
"This remains#{\somekindofmagic} and this does not" # => "This remains"
我假设不是,但我想确保做类似的事情
something.send("#{untrusted_input}=", more_untrusted_input)
实际上并没有留下可以终止内插字符串并用于发送 eval 的某种方式。
在 Ruby 中,有什么方法可以通过插值将数据添加到字符串中来终止字符串?例如:
"This remains#{\somekindofmagic} and this does not" # => "This remains"
我假设不是,但我想确保做类似的事情
something.send("#{untrusted_input}=", more_untrusted_input)
实际上并没有留下可以终止内插字符串并用于发送 eval 的某种方式。
输入字符串数据 AFAIK 是不可能的。RubyString
可以包含任意二进制数据,不应该有String
提前终止的神奇字节组合。
如果您担心对 Ruby 字符串的“注入”式攻击,那么如果输入是已转换为字符串的外部数据的形式,这通常不容易实现(并且您对触发 eval 的特定担忧不会发生)。这种攻击方式依赖于将输入字符串传递给其他解释器(例如 SQL 或 JavaScript)的代码,而没有正确转义语言结构。
但是,如果String
参数以 Ruby 对象的形式来自同一进程中不受信任的 Ruby 代码,则可能会给它们添加副作用:
class BadString
def to_s
puts "Payload"
"I am innocent"
end
end
b = BadString.new
c = "Hello #{b}"
Payload
=> "Hello I am innocent"
编辑:你的例子
something.send("#{untrusted_input}=", more_untrusted_input)
我仍然会稍微担心,如果untrusted_input
真的是不受信任的,那么您将严重依赖这样一个事实,即没有任何方法以=
您不高兴调用的方式结束。有时,由于使用框架或 gem,可以在核心类上定义新方法,而您可能不知道它们,或者它们可能出现在 gem 的更高版本中。出于这个原因,我个人会将允许的方法名称列入白名单,或者对传入数据使用其他验证方案,无论您对开放式评估的安全程度如何。
ruby 中的字符串在内部被处理为堆上的字节数组和保存字符串长度的整数。因此,虽然在 C 中 NUL 字节 ( \0
) 终止了字符串,但在 ruby 中不会发生这种情况。
有关 ruby 字符串内部的更多信息:http : //patshaughnessy.net/2012/1/4/never-create-ruby-strings-longer-than-23-characters(还包括为什么 ruby 字符串超过 23 个字节在红宝石1.9)。