Security DevCenter
oreilly.comSafari Books Online.Conferences.

advertisement




Securing Web Services with mod_security
Pages: 1, 2, 3

Attack vector 2: metacharacter injection

Another major threat to input variables is the use of metacharacters such as %, single quote ('), and double quotes ("). These characters can cause SQL injection attacks to occur and may also cause unnecessary information leakage. Adopting the following strategy provides a sound defense against such attacks.



<Location /axis/getBalance.jws>
   SecFilterInheritance Off
        
   SecFilterDefaultAction "deny,log,status:500"
   SecFilterScanPOST On
   SecFilterCheckURLEncoding On
   SecFilterCheckUnicodeEncoding On
      
   SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>" chain
   SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.{6,}</\s*id\s*>" 
     "deny,status:500"
   SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.*[^a-zA-Z0-9][^<]*</\s*id\s*>" 
     "deny,status:500"      
</Location>

The regular expression pattern <\s*id[^>]*>.*[^a-zA-Z0-9][^<]*</\s*id\s*> denies an HTTP request if a variable's POST_PAYLOAD consists of any characters other than regular string characters. This inverted character set is an important technique in mod_security.

Here is the request and response sent using an id of 12'12:

POST /axis/getBalance.jws HTTP/1.0
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Content-Length: 576
Expect: 100-continue
Host: www.bluebank.example.com

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws" xmlns:types="
http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <soap:Body
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
                <q1:getInput xmlns:q1="http://DefaultNamespace">
                        <id xsi:type="xsd:string">12'12</id>
                </q1:getInput>
        </soap:Body>
</soap:Envelope>

...

500 Internal Server Error
HTTP/1.1 500 Internal Server Error
Date: Mon, 03 Jan 2005 22:00:33 GMT
Server: Apache/2.0.50 (Unix) mod_ssl/2.0.50 OpenSSL/0.9.7d mod_jk2/2.0.4
Content-Length: 657
Connection: close
Content-Type: text/html; charset=iso-8859-1

This attack also failed, and mod_security caught it.

Attack vector 3: SQL injection

It is also possible to inject SQL statements in variables. Concatenating together many SQL statements is possible. If your application does not sanitize its input, malicious clients can append additional SQL statements to existing SQL queries, often with disastrous consequences. Blue Bank has blocked SQL injection attacks by adding the following directives:

<Location /axis/getBalance.jws>
   SecFilterInheritance Off
   SecFilterDefaultAction "deny,log,status:500"
   SecFilterScanPOST On
   SecFilterCheckURLEncoding On
   SecFilterCheckUnicodeEncoding On
 
   SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>" chain
   SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.{6,}</\s*id\s*>" 
     "deny,status:500"
   SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.*[^a-zA-Z0-9][^<]*</\s*id\s*>" 
     "deny,status:500"
   SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.*select.+from[^<]*</\s*id\s*>" 
     "deny,status:500"
</Location>

The highlighted regular expression matches the "select * from . . ." clause and, if matched, will send back status 500 as in the previous case. Similarly, you can add SQL statements for delete, update, and so on. As shown in previous sections, mod_security will defend against these attacks, returning a 500 error.

Attack vector 4: SOAP fault code disclosure

One of the major sources of information in web services is the fault code. A forced error on the server can create a fault code. Here's the request and response from a malicious user probing Blue Bank by sending a request with the character a in the id variable instead of an integer:

POST /axis/getBalance.jws HTTP/1.0
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Content-Length: 569
Expect: 100-continue
Host: www.bluebank.example.com

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws" xmlns:types="
http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
                <q1:getInput xmlns:q1="http://DefaultNamespace">
                        <id xsi:type="xsd:string">a</id>
                </q1:getInput>
        </soap:Body>
</soap:Envelope>

...

500 Internal Server Error
HTTP/1.1 500 Internal Server Error
Date: Tue, 04 Jan 2005 16:22:14 GMT
Server: Apache/2.0.50 (Unix) mod_ssl/2.0.50 OpenSSL/0.9.7d mod_jk2/2.0.4
Set-Cookie: JSESSIONID=1CAF4CD0ED0F38FB40ECBC7BDAB56C75; Path=/axis
Content-Type: text/xml;charset=utf-8
Connection: close

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
   <soapenv:Fault>
        <faultcode>soapenv:Server.userException</faultcode>
        <faultstring>java.lang.NumberFormatException: 
		  For input string:"a"</faultstring>
   <detail/>
   </soapenv:Fault>
  </soapenv:Body>
</soapenv:Envelope>

As shown in the response, the fault code may disclose critical internal information. That's reason enough to define and apply filters. Blue Bank can fix this by applying the following rules:

<Location /axis/getBalance.jws>
   SecFilterInheritance Off
        
   SecFilterDefaultAction "deny,log,status:500"
   SecFilterScanPOST On
   SecFilterCheckURLEncoding On
   SecFilterCheckUnicodeEncoding On
     
   SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>" chain
   SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.{6,}</\s*id\s*>" 
     "deny,status:500"
   SecFilterSelective POST_PAYLOAD "<\s*id[^>]*>.*[^a-zA-Z0-9][^<]*</\s*id\s*>" 
     "deny,status:500"
     
   SecFilterScanOutput On
   SecFilterSelective OUTPUT "faultcode" "deny,status:500"
</Location>
SecFilterScanOutput On

This directive scans an output data block and applies defined filters.

SecFilterSelective OUTPUT "faultcode" "deny,status:500"

This directive blocks outgoing traffic that contains fault codes. If the attacker sends the ill-formed request again with a in the integer field, he will receive a response more like:

HTTP/1.1 500 Internal Server Error
Date: Mon, 03 Jan 2005 22:00:33 GMT
Server: Apache/2.0.50 (Unix) mod_ssl/2.0.50 OpenSSL/0.9.7d mod_jk2/2.0.4
Content-Length: 657
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
   <title>500 Internal Server Error</title>
  </head><body>
  <h1>Internal Server Error</h1>
  <p>The server encountered an internal error or misconfiguration and was
  unable to complete your request.</p>
  <p>Please contact the server administrator,  you@example.com and inform
  them of the time the error occurred, and anything you might have done that
  may have caused the error.</p>
  <p>More information about this error may be available in the server
error 
  log.</p>
  <hr />
  <address>Apache/2.0.50 (Unix) mod_ssl/2.0.50 OpenSSL/0.9.7d
mod_jk2/2.0.4
  Server  at 192.168.7.50 Port 80</address>
</body></html>

mod_security, properly configured, has also defended against this attack.

Conclusion

mod_security may seem like just another tool in the security firmament, but it has a subtle advantage over other security tools already available. While providing intrusion detection and defense capabilities at the HTTP layer, mod_security also allows POST_PAYLOAD filtering capabilities.

However, the advantage mod_security offers is in allowing developers and web administrators to defend web services without actually modifying their source code. This doesn't make shabby code tolerable; it simply means that an organization can mount an additional effective defense of its web services without having to run through numerous lines of code.

This article focuses on just one of the techniques for securing web services, and an effective one too. Feel free to choose your own techniques of defending web services.

For more information on mod_security, see Introducing mod_security, mod_security quick examples, and HOWTO: Enhancing Apache with mod_security.

Shreeraj Shah is the founder of Blueinfy, a company that provides application security services.


Return to the Security DevCenter.




Sponsored by: