Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: integration of hashed passwords into xml example

...

Code Block
<users>
  <user>
    <username>Utah</username>
    <password>C^f3<<password>e90205372a3b89e2</password>
  </user>
  <user>
    <username>Bohdi</username>
    <password>C@fe<<password>6c16b22029df4ec6</password>
  </user>
  <user>
    <username>Busey</username>
    <password>cAf3<<password>ad39b3c2a4dabc98</password>
  </user>
</users>

The passwords are hashed in compliance with MSC66-JG. Store passwords using a hash function.

Untrusted code may attempt to retrieve user details from this file with an XPath statement constructed dynamically from user input:

...

If an attacker knows that Utah is a valid user name, he or she they can specify an input such as the following:

...

Code Block
//users/user[username/text()='Utah' or '1'='1' and password/text()='xxxx' ]

Because the '1'='1' is automatically true, the password is never validated. Consequently, the attacker is inappropriately authenticated as user Utah without knowledge of user Utah's password.

Compliance with MSC66-JG. Store passwords using a hash function requires encrypting the passwords. Unfortunately, many small systems fail to comply with MSC51-J, so the password text added in the query string would match precisely what the user enters. An attacker could supply a password such as

Code Block
' or '1'='1

This yields the following query string:

Code Block
//users/user[username/text()='xxxx' and password/text()='' or '1'='1' ]

This time, the '1'='1' tautology disables both name and password validation, and the attacker is inappropriately authenticated without knowledge of either a user name or a password.

Noncompliant Code Example

This noncompliant code example reads a user name and password from the user and uses them to construct the query string. The password is passed as a char array, and then hashed,  to comply with MSC66-JG. Store passwords using a hash function and MSC63-JG. Limit the lifetime of sensitive data..  This example is vulnerable to the attack described earlier. If the attack string described earlier is passed to evaluate(), the method call returns the corresponding node in the XML file. This causes the doLogin() method to return true and bypass any authorization.

Code Block
bgColor#FFcccc
private boolean doLogin(String userName, char[] password)
  throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {

  DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
  domFactory.setNamespaceAware(true);
  DocumentBuilder builder = domFactory.newDocumentBuilder();
  Document doc = builder.parse("users.xml");
  String pwd = hashPassword( password);

  XPathFactory factory = XPathFactory.newInstance();
  XPath xpath = factory.newXPath();
  XPathExpression expr = xpath.compile("//users/user[username/text()='" +
       userName + "' and password/text()='" + pwd + "' ]");
  Object result = expr.evaluate(doc, XPathConstants.NODESET);
  NodeList nodes = (NodeList) result;

  // Print first names to the console
  for (int i = 0; i < nodes.getLength(); i++) {
    Node node = nodes.item(i).getChildNodes().item(1).getChildNodes().item(0);
    System.out.println( "Authenticated: " + node.getNodeValue());
  }

  return (nodes.getLength() >= 1);
}

...