Sunday, November 25, 2007

Hourly Clock

Announcing the availability of Hourly Clock a Google Gadget developed by me. It uses the nice Google gadget API to show a simple clock and give hourly reminders of the time. So don't let the time just pass by, use this gadget....

Non WS-I document literal web service

A document literal web service with more than one parts specified for the same message is not WS-I compliant.

<wsdl:message name="HelloDudeSoapIn">
<wsdl:part name="name" element="tns:name"/>
<wsdl:part name="age" element="tns:age"/>

The SOAP message would look like:


Why the restriction, think about validation of the message. I would have to extract the name and age elements seperately and then validate them against an XSD. If the elements were within a single tag...


The person element can be completely validated after the person element is extracted.

Wednesday, November 14, 2007

XPath injection

XPath injection

What is XPath?

XPath (XML Path Language) is an expression language for addressing portions of an XML document, or for computing values (strings, numbers, or boolean values) based on the content of an XML document.
For more information see XPath tutorial.

Understanding the attack

XPath injection is an attack where data is taken from the user without validation (or incomplete validation) and which modifies the behavior of the XPath expression by masquerading XPath as data.

Assume that we have user id and password stored in xml files and we use XPath for validating them. The xml containing the user id and password looks like:


To validate the user id and password against the xml we use the XPath expression
//user[id/text()='+ {input user id} +' and password/text()='+ {input password} +']
we execute the XPath and check if it returns any nodes, if it returns any nodes then the password is valid. If the entered used id is sash and the password is sash123 the XPath would become
//user[id/text()='sash' and password/text()='sash123']

and would return the user node and the password would be validated. If a wrong password is used no node would be returned and the validation would fail.

Now while injecting XPath in the password field ' or 'a' = 'a is entered. The XPath would become
//user[id/text()='sash' and password/text()='' or 'a' = 'a']
which would return multiple rows and the validation would pass.

Simulating the attack

Sample C# code

XmlDocument XmlDoc = new XmlDocument();
XmlDoc.Load("XPATH_INJECT.xml"); // use the same xml as above
XPathNavigator nav = XmlDoc.CreateNavigator();
XPathExpression expr = nav.Compile(
+ textBox1.Text + "' and password/text()='" + textBox2.Text + "']");

XPathNodeIterator iterator = nav.Select(expr);
if (iterator.MoveNext())
result.Text = "passed";
result.Text = "failed";

Sample Java code

XPathFactory factory = XPathFactory.newInstance();
XPath xPath = factory.newXPath();
File xmlDocument = new File("XPATH_INJECT.xml");
InputSource inputSource = new InputSource(
new FileInputStream(xmlDocument));

String user = jTextField1.getText().trim();
String pwd = jTextField2.getText().trim();
XPathExpression expr = xPath.compile(
"//user[id/text()='" + user +
"' and password/text()='" + pwd +
"' ]");
Object result = expr.evaluate(inputSource, XPathConstants.NODESET);

NodeList nodes = (NodeList) result;

jLabel3.setText("Valid"); }
jLabel3.setText("Failed"); }

How to protect against the attack:

There are many ways of preventing this attack

  1. Validate the input
  2. Escape the ' or '' characters
  3. This attack is similar to SQL injection, the most common solution to SQL injection attack is using a prepared statement, but something similar is not available in XPath. This though can be achieved using XQuery but XQuery is not directly supporeted without the use of external libraries in .Net or Java.

The best solution would be escaping the ['] characters, in our example if we replace a ['] with [']['] in the input, we would avoid the attack.
In the previous case our password text entered was ' or 'a' = 'a but this would be modified to '' or ''a'' = ''a
//user[id/text()='sash' and password/text()=''' or ''a'' = ''a']
and would not produce any results (and it is a valid XPath).

This XPath passes in Altova XML spy but not in Java 6 or .Net 2.0

So we still need to find an elegant solution to the problem!!!!

In all the proposed solutions solution (3) is the most elegant but the support is still very limited.

Whats left

Some of the databases now support XPath, in case your database supports XPath be very careful about the inputs (don't forget the validation).