是否可以对redis查询运行字符串注入攻击?

pfo*_*oti 9 ruby-on-rails redis

我正在为我的(基于rails的)api服务器构建一个基于令牌的认证库,它使用redis来存储生成的auth令牌.我担心的是:user_id = $redis.get("auth:#{token}"),令牌是传递给authenticate_or_request_with_http_token的地方.

如果这是SQL,那将是一个巨大的红旗 - 字符串插值SQL查询非常不安全.但是,据我所知,在redis密钥查询上进行字符串插值并不安全.

我上面提到的声明的来源是redis文档:http://redis.io/topics/security (在字符串转义和nosql注入标题下),但我想确保在我得到一个Bobby之前就是这种情况表攻击.

Pas*_*rer 10

您指向的文档非常明确:

Redis协议没有字符串转义的概念,因此在正常情况下使用普通客户端库无法进行注入.该协议使用前缀长度字符串,完全是二进制安全的.


her*_*rzi 9

这些类型的字符串注入有一个小的攻击向量.虽然redis文档清楚地说明了在数据库上执行多个命令的难度,但它没有提到密钥分隔符(在您的示例中为':')在用作密钥的一部分时通常需要进行转义.

我见过使用这些密钥的redis数据库:

  • oauth_token:123456 (包含OAuth令牌参数的散列)和
  • oauth_token:123456:is_temp (其中包含一个布尔属性,用于指示OAuth令牌是否为临时令牌)

信任用户输入而不转义可能会导致GET oauth_token:#{token}意外结束GET oauth_token:123456:is_temp(当123456:is_temp用户设置了令牌时).

所以我强烈建议从潜在的用户输入中正确地逃避冒号,以确保您的密钥路径不会像这样被欺骗.

注意:有人建议使用oauth_token:123456和修复上面的示例oauth_token:is_temp:123456,但这是有缺陷的(对于用户提供的令牌is_temp:123456).该问题的正确解决方案(没有转义)将是使用密钥oauth_token:info:123456oauth_token:is_temp:123456确保这些密钥不会重叠任何用户提供的输入(或简单地逃避冒号).


ant*_*rez 5

基本上,当逐字使用输入字符串时,Redis 不会出现转义问题。例如:

SET mykey <some-attacker-chosen-data>
Run Code Online (Sandbox Code Playgroud)

然而,正如 Sven Herzberg 所示,Redis 也无法避免在字符串插值上下文中使用非验证输入所引起的问题。为了将 Sven 示例变成安全示例,可以仅使用哈希,并避免恢复为插值。否则,要么使用不常见的前缀与键插值结合使用,要么对输入使用某种基本形式的健全性检查,即过滤掉所使用的分隔符,或者更好的是,验证输入实际上是一个数字(在特定的情况下)例子)。

因此,虽然 Redis 不会遭受典型的 SQL 注入攻击,但当在用于创建键名的字符串插值上下文中使用不受信任的输入时,或者更糟糕的是,在 Lua 脚本中,应该小心一些。