Tuesday, May 16, 2006 4:31 PM
codingsanity
Connection strings in the QueryString
Please go and have a look at this article on putting connection strings into the query string. The author, Peter Bromberg Ph.D. is an MVP who has worked in the banking and financial industry for 20 years.
So what exactly is wrong with this?
Never trust user input
This is one of the cardinal tenets of security. What we're doing here is using untrusted user input to connect to a database. Let's look at some examples of what we can do. First off, let's say that the web site is going to put sensitive information into the database. Well, easy, we just give it a connection string for a box which we own and voila the sensitive information is on our box.
If the web server connects to the DB whilst in a trusted user account, and we pass through a connection string containing "Integrated Security=true", then we now have elevated privileges. So, if the web page had a SQL Injection problem, we can now play around to our hearts content.
Sniffing
Now, let's say that I'm running a packet sniffer. If I'm able to see the traffic to the box coming past, I can get this connection string and use it for myself. I'm willing to bet you that someone, somewhere will pass me the sa password this way. Yippee! I now 0wn your SQL Server.
Encryption?
Okay, so we've looked at a very few of the reasons why having the connection string in the query string is a VBI (Very Bad Idea). Now let's have a look at the "encryption" Peter uses. I do not like his naming his class and methods with "Encryption" in them, since they are nothing of the sort. Encoding is a better term for this. You know, like base64 encoding, or UTF8 and so forth.
Encoding is better because it doesn't imply that there's encryption involved here, since there isn't. Why do I say that? Well, let's start with the "encryption" methods Peter looked at:
XOR Encryption
He rightly rejected this one. We take the plaintext, and our key and XOR them together. So, for example if our key was "hello world", and our plaintext was "server=mine", we'd take the ASCII of "s" and XOR that with the ASCII of "h", which would give us an apostrophe. The second letter would give us a bit of a problem though, it would be "e" XOR "e" which would be NULL, ending our string right there. In any case this encryption method is "trivially simple" to crack. It does have one advantage though, it's a proper encryption method, since in theory at least the key is required to decrypt. Of course, with even a large random key, it's easy to brute force this one.
ROT13 Encryption
This involves treating the alphabet as a loop (so after "Z" is "A"), and simply shifting each character right 13 places. Thus "A" becomes "N", and "B" becomes "O". Nicely though, simply reapplying the cipher gives you the cleartext. In essence, to crack this code requires one CPU instruction per letter. Nice and quick to encrypt and decrypt. It belongs to a class of ciphers known as "Caeser ciphers" or "shift ciphers", yep, that's right it's a cipher dating back to before 44 BC. ROT13 is about as secure as writing the plaintext. However, it is at least a cipher, if a spectacularly poor one.
ROT39 Encryption
Same as ROT13, but expanded to use the ASCII character set from 48 "0" to 125 "}". Just as easy to crack, slightly more difficult to identify with the naked eye.
ASCII to Hex "Encryption"
This is the "encryption" method Peter settled on. The reason I put encryption in quotes is that this is not an encryption method, it's an encoding method. In .NET just take each 2 character piece, and call byte.Parse("63", NumberStyles.HexNumber) to get "c". If you look at his code this is exactly what he is doing. It's plaintext, just not "normal" plaintext. It's worse than even ROT13 for goodness sakes!
Conclusion
Now Peter does say in his article that this is obfuscation rather than encryption. He then suggests that proper encryption (e.g. Triple-DES) could be used, but goes on to say that this would be "overkill". I dunno, passing connection strings around on a query string suggests a VERY strong need for overkill to me. If I had to pass such sensitive data around in the querystring, I'd...
Well, I wouldn't. Flat out no. No matter what encryption, no matter what security, nu-uh, no way. To be fair to Peter he does point out that "it's best not to put sensitive data on the querystring at all". Good, so why suggest it in the newsgroups, and why write an article showing exactly how to do that? Especially one with far too few caveats on the dangers IMO.
Please, please, please, do NOT follow the suggestions in his article. That's not to say you shouldn't use his code, nor obfuscate stuff on the querystring, please do; just not sensitive data. You could perhaps obfuscate things like whether the user is in edit mode or not, or whether to display comments or not. It should not be used for anything that is trusted. If he'd strongly pointed out that, I would be a whole lot happier with his article.