For optimized display of this website, it is recommended to use a free and secure browser: Firefox. Tell Me Why!

Home · Hacking · Tutorials · Hacking A Web App With SQL Injection Through HTTP Headers

Hacking A Web App With SQL Injection Through HTTP Headers

During vulnerability assessment or penetration testing, identifying the input vectors of the target application is a primordial step. Sometimes, when dealing with Web application testing, verification routines related to SQL injection flaws discovery are restricted to the GET and POST variables as the unique inputs vectors ever. What about other HTTP header parameters? Aren’t they potential input vectors for SQL injection attacks? How can one test all these HTTP parameters and which vulnerability scanners to use in order to avoid leaving vulnerabilities undiscovered in parts of the application?

Disclaimer: the content of this article is meant for educational purposes only. This tutorial is intended for developers who wish to protect their website / server more efficiently, and therefore need to know how the attackers proceed. Neither I, nor my web host will be held responsible for what you decide to do with this knowledge.

Input Parameter Coverage in Security Web Application Scanners

A result of a comparison of 60 commercial and open-source black box web application vulnerability scanners was released and titled: « The Scanning Legion: Web Application Scanners Accuracy Assessment & Feature Comparison ». This benchmark, realized by the security researcher Shay Chen in 2011, focused on testing commercial and open source tools that are able to detect (and not necessarily exploit) security vulnerabilities on a wide range of URLs. We have concluded the chart below which shows input parameter’s coverage supported by tested web application scanners. These inputs are basically:

- HTTP Query String Parameters (GET): input parameters sent in the URL.
- HTTP Body Parameters (POST): input parameters sent in the HTTP body.
- HTTP Cookie Parameters : input parameters sent in the HTTP cookie.
- HTTP Headers : HTTP request headers used by the application.

This chart shows obviously that 75% of Web application scanners couldn’t discover HTTP Headers parameters related flaws. Furthermore, 70% of these scanners failed inspecting HTTP Cookies vulnerabilities else. These rates refer exactly to the ability of the scanners to scan the input vector, not simply to interpret it. Comparing to the reasonable score made for GET and POST, some automated testing tools may lead to unsatisfied results when dealing with HTTP header as an SQL injection input vector.

As a matter of fact, HTTP Headers and Cookies should not be underestimated. Therefore, these two vectors should be taken into consideration during testing plan. Yet, when the vulnerability scanners used are not supporting these features, we should think about testing these parameters manually.

Potential HTTP Headers for SQL injections

HTTP Header fields

HTTP header fields are components of the message header of requests and responses in the Hypertext Transfer Protocol (HTTP). They define the operating parameters of an HTTP transaction.

Example: Request HTTP

GET / HTTP/1.1
Connection: Keep-Alive
Keep-Alive: 300
Host: host
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
rv: Gecko/20110319 Firefox/3.6.16 ( .NET CLR 3.5.30729; .NET4.0E)
Cookie: guest_id=v1%3A1328019064; pid=v1%3A1328839311134

We can consider the HTTP Cookies, when are stored in databases for sessions identification, as the first potential HTTP variables which should be tested. We will see next in an example of Cookie based SQL injection. There are also other HTTP headers related to the application.


X-Forwarded-For is an HTTP header field considered as a de facto standard for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer.

We will see an example of this flaw basing of a form submission.

$req = mysql_query("SELECT user,password FROM admins WHERE user='".sanitize($_POST['user'])."' AND password='".md5($_POST['password'])."' AND ip_adr='".ip_adr()."'");

The variable login is correctly controlled due to the sanitize() method.

function sanitize($param){
	if (is_numeric($param)) {
		return $param; 
	else {
		return mysql_real_escape_string($param);
		} }

Let us inspect the ip variable. It is allocating the output of the ip_addr() method.

function ip_adr() { 
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
         $ip_adr = $_SERVER['HTTP_X_FORWARDED_FOR']; 
          else { 
             $ip_adr = $_SERVER["REMOTE_ADDR"]; 
         if (preg_match("#^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}#",$ip_addr)) { 
                return $ip_adr; 
            else { 
                  return $_SERVER["REMOTE_ADDR"]; 
         } }

Obviously, the IP address is retrieved from the HTTP header X_FORWARDED_FOR. This later is controlled by the preg_match which verifies if this parameter does hold at least one IP address. As a matter of fact, the environment variable HTTP_X_FORWARDED_FOR is not properly sanitized before its value being used in the SQL query. This can lead to run any SQL query by injecting arbitrary SQL code into this field.

The simple modification of this header field to something like:

GET /index.php HTTP/1.1
Host: [host]
X_FORWARDED_FOR :' or 1=1#

will lead to bypass the authentication control.


User agent is an HTTP header field gives the software program used by the original client. This is for statistical purposes and the tracing of protocol violations. It should be included. The first white space delimited word must be the software product name, with an optional slash and version designator.

Not all applications are written to capture the user-agent data, but sometimes applications are designed to store such information (ex: shopping cart providers) to make use of it. In this case, it’s worth investigating the user-agent header for possible issues.

HTTP query example:

GET /index.php HTTP/1.1
Host: [host]
User-Agent: aaa' or 1/*


Referer is another HTTP header which can be vulnerable to SQL injection once the application is storing it in database without sanitizing it. It’s an optional header field that allows the client to specify, for the server’s benefit, the address ( URI ) of the document (or element within the document) from which the URI in the request was obtained. This allows a server to generate lists of back-links to documents, for interest, logging, etc. It allows bad links to be traced for maintenance. Example:

GET /index.php HTTP/1.1
Host: [host]
User-Agent: aaa' or 1/*

Attacker’s perspective?

As we all know, injection flaws are ranked the first in The OWASP Top 10 Web Application Security Risks. Attackers are increasingly seeking for injection points to get full access of your databases. No matter the injection input vector’s type, whether it’s a GET, POST, Cookie or other HTTP headers; the important for intruders is always to have at least one injection point which let them start the exploitation phase.

Manually testing Cookie based SQL injections

In this section, we will introduce some methods of inspecting HTTP Cookie variables.

Using a Browsers Add-on

Cookies Manager+

Cookie Manager+ allows view, edit and create new cookies. It also allows show extra information about cookies and allows edit multiple cookies at once, as well as backup/restore them. After installing it, from the Tools menu, select Cookies Manager+. We select a Cookie variable related to the target application.

We will edit the language_id variable. To figure out the SQL injection flaw, we will add a quote “‘” in the field content of the variable language_id.

After refreshing the page, or clicking on other internal link of the application, the application submits the request using the edited HTTP cookie. The result is triggered an SQL error:

This database error is alerting us for a susceptible SQL injection flaw.

The advantage of using Cookies Manager+ is that it’s simple to use, act directly on the cookie and saves the previous edited value of the cookie.

We will try to determine the number of columns using another Firefox plug-in.

Tamper Data

Tamper Data is a powerful Firefox add-on to view and modify HTTP/HTTPS headers and post parameters. After installing it, from the Tools menu, select Tamper Data. Start tampering HTTP requests by clicking the button Start Tamper. When launching any request from the target application, Tamper Data pops up a box and asks if we want to tamper the current HTTP request just sent. After clicking on Tamper, we got the full Tamper popup.

We are going to add: order by 4 into the HTTP cookie variable as shown in the previous screenshot, and we are going to test and increment to 5, 6, 7 etc. until we get an error from the database. The response is normal from the application.

Finally, we get an error by entering order by 5 into the HTTP cookie variable, so we can conclude that the number of columns is 4.

Now, we will try to figure out the affected columns in order to inject in it more SQL queries. So, we will add the following query into the language_id HTTP cookie variable:


The exploitation may need sometimes advanced SQL injection techniques.

Using automated penetration testing scanner

Sqlmap as example

Sqlmap is a popular open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers. Sqlmap supports the HTTP cookie features so it can be useful in two ways:

- Authentication based upon cookies when the web application requires that.
- Detection and exploitation of SQL injection on such header values.

By default, sqlmap tests all GET parameters and POST parameters. When the value of –level is set to 2 or above it tests also HTTP Cookie header values. When this value is set to 3 or above, it tests also HTTP User-Agent and HTTP Referer header value for SQL injections. It is however possible to manually specify a comma-separated list of parameter(s) that you want sqlmap to test. This will bypass the dependence on the value of –level too. For instance, to test for GET parameter id and for HTTP User-Agent only, provide -p id,user-agent.

This is an example of how we can test the parameter named security of an HTTP Cookie of the DVWA (Damn Vulnerable Web Application).

./ -u ''
--cookie='PHPSESSID=0e4jfbrgd8190ig3uba7rvsip1; security=low'
--string='First name' --dbs --level 3 -p PHPSESSID

The flag –string compares between the valid pages and the invalid one (due to the injection). On the other hand, the flag –dbs is used to enumerate the database management systems. Finally, the flag –p forces the testing of the PHPSESSID variable.

Sources: Wikipedia, Google, Infosec, Enigmagroup, The Web Application Hacker's Handbook, 2nd Edition.


Comment By thalasso | 23.01.2013

Thanks for a marvelous posting! I certainly enjoyed reading it, you happen to be a great author.
I will make certain to bookmark your blog and will eventually come back later in
life. I want to encourage you to continue your great work, have
a nice weekend!

Comment By free minecraft code | 22.09.2013

Thanks for sharing your thoughts about sql.