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

时间:2014-02-25 18:53:11

标签: 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 Tables攻击。

3 个答案:

答案 0 :(得分:10)

您指向的文档非常明确:

  

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

答案 1 :(得分:8)

对于这些类型的字符串注入,存在一个小的攻击向量。虽然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:123456oauth_token:is_temp:123456修复上述示例,但这有缺陷(对于用户提供的令牌is_temp:123456) 。该问题的正确解决方案(无需转义)将使用密钥oauth_token:info:123456oauth_token:is_temp:123456来确保这些密钥不会重叠任何用户提供的输入(或简单地转义冒号)。

答案 2 :(得分:3)

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

SET mykey <some-attacker-chosen-data>

然而,正如Sven Herzberg所示,在字符串插值的上下文中使用非验证输入所引起的问题,Redis无法免疫。为了将Sven示例转换为安全示例,可以使用Hash,并避免恢复插值。否则要么使用不常用的前缀与键插值一起使用,要么对输入使用一些基本形式的完整性检查,即过滤掉使用的分隔符,或者更好,验证输入实际上是一个数字(具体来说)例子)。

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