SQL Injection Through Cookies
Through my career as a developer I’ve seen many developers that are not aware about the possibility of SQL injection through cookies. Cookies in fact is a user input and as any input it must be validated and because normal users don’t see cookies that doesn’t mean attackers won’t temper with it, so developers must always validate cookies the same way they validate any other type of input. I will demonstrate in this article how it’s possible to an attacker to make a SQL injection attack through cookies. Say we have a web application admin page that hashes the admin password and store it in a cookie so next time the admin opens the web application administrator panel web page the application will recognize him/her as admin, the password is hashed in a cookie so it won’t be stored in plain text in cookies which is a bad security practice. So let’s say we have the following code
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Cookies.Get("password_hash") != null)
{
//check if the password hash is authentic
string sql = "select count(id) from admins where password_hash = '" + Request.Cookies.Get("password_hash") + "'";
//the rest of database access code and admin
//authentication goes here
}
else Response.Redirect("login.aspx");
}
Now the code looks pretty sweet and simple, if there is no cookie the admin will be redirected to the login page else we will check if the password hash exists in the database or not, if yes we will log in the admin if not then the cookie has expired and we will redirect the admin to the login page, the cookie is hashed so if an attacker managed to get it, at least it won’t be in a plain text format and also it’s a hash (i.e. one way encryption) so the attacker will have a hard time cracking it and anyway by the time the attacker will get the hash it will be expired anyway. And of course there will be a security policy that forces our admin to change the password every 10 days. So now our security plan sounds pretty hard to break.
Our admin cookie should look like this
GET /admin/admins.aspx HTTP/1.1
Accept: */*
Accept-Language: en-us
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.590; .NET CLR 3.5.20706)
Proxy-Connection: Keep-Alive
Host: www.host.com
Pragma: no-cache
Cookie: password_hash=d41d8cd98f00b204e9800998ecf8427e
But what if an attacker tempered with the cookies and sent us a GET request that looks like this
GET /admin/admins.aspx HTTP/1.1
Accept: */*
Accept-Language: en-us
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.590; .NET CLR 3.5.20706)
Proxy-Connection: Keep-Alive
Host: www.host.com
Pragma: no-cache
Cookie: password_hash= SorryIDontHaveYourHash ' or 1=1 --
Pay some attention to the cookie line
Cookie: password_hash=SorryIDontHaveYourHash' or 1=1 --
Notice what it has in its end? Now let’s imagine how our SQL query will look like if the attacker did this
select count(id) from admins where password_hash = 'SorryIDontHaveYourHash' or 1=1 --'
This SQL query will return records every time it executes and our application will think that the cookie have a valid password hash although it doesn’t and will log the attacker as the admin. I hope you now understand the dangers that come from not validating your cookies the same as you validate user input. Thanks for reading and I would really appreciate your feedback.