mod_security SQL injection rules and Django cookies

273 views
Skip to first unread message

Nikolai Prokoschenko

unread,
Sep 19, 2014, 7:50:33 AM9/19/14
to django-d...@googlegroups.com
Hello,

(disclaimer: it's a security question and I don't have any proper expertise in this area, so please bear with me)

the people responsible for the Apache part of our Django application have recently introduced a policy for mandatory use of mod_security with OWASP ruleset. The SQL injection rule [1], has raised their attention, because it has found substrings like "XOr" and "0xa66e" in the "sessionid" and "csrftoken" cookies and has rejected the appropriate requests as a possible SQL injection attack (apparently, a known phenomenon in other environments as well [2]).

Based on that, we now have a request on the table to change hash key generation to something that doesn't produce any substrings looking like SQL (e.g. producing no more than two alphabetical symbols in a row or using hex strings). I consider this extremely risky, since the chance of session ID collisions increases noticeably (and on top of that, I don't want to go forking Django code). On the other hand, they consider disabling that rule risky since they think they'd be missing SQL injections; which shouldn't be a problem in my opinion, because we don't put raw cookie values into raw SQL statements (but they'd have to take my word for it) and everything else is ORM-managed.

I think I can argue against changing the hash generation routine and in favor of killing the mod_security rule. However, I'd like to have some additional information from Django developers to strenghten my case a bit.

1. Has there been some security audit in the past which confirmed that session ID handling inside Django is not vulnerable to SQL injection attacks?

2. Can I argue that Django's ORM is SQL injection safe (we are 99% ORM-based)?

3. In general, is my assumption correct that I'd be vastly reducing entropy if I implemented a session handler with different key generation? I can't really analyze [3] for collisions probability, esp. since it's not one of the usual suspects (MD5/SHA1/SHA256/etc.), but have a feeling that anything I'd produce will have a much higher percentage.

If anyone had experienced a similar problem with mod_security, I'd be happy to hear how you resolved it or how you would have resolved it if you were in charge.

Thanks!



Florian Apolloner

unread,
Sep 19, 2014, 8:00:17 AM9/19/14
to django-d...@googlegroups.com
Hi Nikolai,


On Friday, September 19, 2014 1:50:33 PM UTC+2, Nikolai Prokoschenko wrote:
1. Has there been some security audit in the past which confirmed that session ID handling inside Django is not vulnerable to SQL injection attacks?

Nothing public that I am aware of, no.

2. Can I argue that Django's ORM is SQL injection safe (we are 99% ORM-based)?

Yes, at least there is no known problem in any backend (shipped with Django).
 
3. In general, is my assumption correct that I'd be vastly reducing entropy if I implemented a session handler with different key generation? I can't really analyze [3] for collisions probability, esp. since it's not one of the usual suspects (MD5/SHA1/SHA256/etc.), but have a feeling that anything I'd produce will have a much higher percentage.

Depending on how exactly you generate the key, you can be fine. So as an example: assuming you'd just have 0-9 and a-j and choose one item out of those every second step you'll have the same entropy as just choosing from 0-9 all the time, but once you choose from 0-9 & a-j every time you have a higher space. That said, if you increase the length enough, you can make up for it (though you'd have to check if Django has problems with longer session ids).

Cheers,
Florian

Carl Meyer

unread,
Sep 19, 2014, 11:56:08 AM9/19/14
to django-d...@googlegroups.com
Hi Nikolai,

On 09/19/2014 05:50 AM, Nikolai Prokoschenko wrote:
> the people responsible for the Apache part of our Django application
> have recently introduced a policy for mandatory use of mod_security with
> OWASP ruleset. The SQL injection rule [1], has raised their attention,
> because it has found substrings like "XOr" and "0xa66e" in the
> "sessionid" and "csrftoken" cookies and has rejected the appropriate
> requests as a possible SQL injection attack (apparently, a known
> phenomenon in other environments as well [2]).
>
> Based on that, we now have a request on the table to change hash key
> generation to something that doesn't produce any substrings looking like
> SQL (e.g. producing no more than two alphabetical symbols in a row or
> using hex strings). I consider this extremely risky, since the chance of
> session ID collisions increases noticeably (and on top of that, I don't
> want to go forking Django code). On the other hand, they consider
> disabling that rule risky since they think they'd be missing SQL
> injections; which shouldn't be a problem in my opinion, because we don't
> put raw cookie values into raw SQL statements (but they'd have to take
> my word for it) and everything else is ORM-managed.
>
> I think I can argue against changing the hash generation routine and in
> favor of killing the mod_security rule. However, I'd like to have some
> additional information from Django developers to strenghten my case a bit.
>
> 1. Has there been some security audit in the past which confirmed that
> session ID handling inside Django is not vulnerable to SQL injection
> attacks?

Not that I'm aware of.

> 2. Can I argue that Django's ORM is SQL injection safe (we are 99%
> ORM-based)?

There aren't known SQL-injection bugs in the ORM (unless of course you
use .raw() or .extra() or undocumented internal APIs and concatenate SQL
strings unsafely yourself), and any SQL-injection bug found would result
in a fix and security release.

> 3. In general, is my assumption correct that I'd be vastly reducing
> entropy if I implemented a session handler with different key
> generation? I can't really analyze [3] for collisions probability, esp.
> since it's not one of the usual suspects (MD5/SHA1/SHA256/etc.), but
> have a feeling that anything I'd produce will have a much higher percentage.

The docstring for `get_random_string` already gives you the equation for
the number of bits of entropy; it's not hard to calculate. It should be
easy enough to adjust that for different character sets and string
lengths and find something with equivalent entropy to the default.
Obviously, as Florian says, if you're decreasing the size of the
character set you'll need to increase the length to compensate.

I can't say for sure without checking, but I would be very surprised if
anything in Django's session code has a hard restriction to a length of
12 characters.

Carl

Nikolai Prokoschenko

unread,
Sep 19, 2014, 1:43:53 PM9/19/14
to django-d...@googlegroups.com
Hello Carl, hello Florian,

thank you for your both replies, I feel confident that we'll sort it out now.


On Friday, September 19, 2014 5:56:08 PM UTC+2, Carl Meyer wrote:

I can't say for sure without checking, but I would be very surprised if
anything in Django's session code has a hard restriction to a length of
12 characters.

As far as I can see, a session ID is 32 characters per default and the default database backend model has a max_length of 40, so that's the only restriction there is. But I hope I can avoid subclassing a SessionStorage altogether.

Nikolai.
Reply all
Reply to author
Forward
0 new messages