I'm building a little token-based authentication library for my (rails based) api server which uses redis to store generated auth tokens. The line I'm worried about is: user_id = $redis.get("auth:#{token}")
, where token is what's passed in to authenticate_or_request_with_http_token.
If this were SQL, that'd be a huge red flag - string interpolated SQL queries are pretty insecure. As far as I can tell, however, doing string interpolation on a redis key query isn't insecure.
My source for the above claim is the redis documentation here: http://redis.io/topics/security (under the string escaping and nosql injection header), but I wanted to make sure that this is the case before I get a Bobby Tables attack.
Redis has low security on its own, so it's important to set up a firewall. Setting up a proper firewall configuration will prevent any unauthorized incoming traffic. Some commands are considered dangerous and could be run by mistake or by an unauthorized user.
SQL injection (SQLi) is a web security vulnerability that allows an attacker to interfere with the queries that an application makes to its database.
NoSQL injection is a security weakness in a web application that uses a NoSQL database. NoSQL (Not Only SQL) refers to database systems that use more flexible data formats and do not support Structured Query Language (SQL). They typically store and manage data as key-value pairs, documents, or data graphs.
There is a small attack vector for these kinds of string injections. While the redis documentation is clear about the difficulty of executing multiple commands on the database, it does not mention that the key separator (':' in your example) usually needs to be escaped when used as the part of a key.
I have seen a redis database using these keys:
oauth_token:123456
(which contained a hash of OAuth token parameters) andoauth_token:123456:is_temp
(which contained a boolean property to indicate whether the OAuth token is a temporary token)Trusting the user input without escaping might result in GET oauth_token:#{token}
accidentally ending up as GET oauth_token:123456:is_temp
(when token has been set to 123456:is_temp
by the user).
So I highly recommend to properly escape colons from potential user input to make sure your key paths cannot be tricked like this.
NOTE: Someone recommended to fix the example above by using oauth_token:123456
and oauth_token:is_temp:123456
, but that is flawed (for the user-provided token is_temp:123456
). The correct solution to that problem (without escaping) would be to use keys oauth_token:info:123456
and oauth_token:is_temp:123456
to make sure these keys cannot overlap whatever the user-provided input was (or simply escape colons).
The documentation you are pointing to is quite explicit:
The Redis protocol has no concept of string escaping, so injection is impossible under normal circumstances using a normal client library. The protocol uses prefixed-length strings and is completely binary safe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With