This rule identifies potential security vulnerabilities in your code where an XPath expression may be influenced by data coming from an HTTP request. This could lead to what is known as an XPath Injection attack, where an attacker could manipulate the XPath query to access unauthorized data, or potentially cause other harmful effects.
This rule is crucial because XPath Injection is a severe security risk, similar to SQL Injection. If an attacker can control part of an XPath query, they can alter the query’s logic, leading to unauthorized access or exposure to sensitive data.
Never construct XPath queries using string concatenation with unvalidated input. Instead, always use parameterized queries or sanitize the input before using it in an XPath query. If possible, limit the XPath functionality that your application uses to reduce the attack surface. You can also use APIs that automatically protect against XPath Injection, or use a web application firewall to detect and block attack attempts.
Non-Compliant Code Examples
@WebServlet(value="/xpathi-00/BenchmarkTest01223")publicclassBenchmarkTest01223extendsHttpServlet{privatestaticfinallongserialVersionUID=1L;@OverridepublicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{doPost(request,response);}@OverridepublicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{response.setContentType("text/html;charset=UTF-8");Stringparam="";java.util.Enumeration<String>headers=request.getHeaders("BenchmarkTest01223");if(headers!=null&&headers.hasMoreElements()){param=headers.nextElement();// just grab first element}// URL Decode the header value since req.getHeaders() doesn't. Unlike req.getParameters().param=java.net.URLDecoder.decode(param,"UTF-8");Stringbar=newTest().doSomething(request,param);try{java.io.FileInputStreamfile=newjava.io.FileInputStream(org.owasp.benchmark.helpers.Utils.getFileFromClasspath("employees.xml",this.getClass().getClassLoader()));javax.xml.parsers.DocumentBuilderFactorybuilderFactory=javax.xml.parsers.DocumentBuilderFactory.newInstance();// Prevent XXEbuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);javax.xml.parsers.DocumentBuilderbuilder=builderFactory.newDocumentBuilder();org.w3c.dom.DocumentxmlDocument=builder.parse(file);javax.xml.xpath.XPathFactoryxpf=javax.xml.xpath.XPathFactory.newInstance();javax.xml.xpath.XPathxp=xpf.newXPath();Stringexpression="/Employees/Employee[@emplid='"+bar+"']";xp.compile(expression).evaluate(xmlDocument,javax.xml.xpath.XPathConstants.NODESET);response.getWriter().println("Your query results are: <br/>");for(inti=0;i<nodeList.getLength();i++){org.w3c.dom.Elementvalue=(org.w3c.dom.Element)nodeList.item(i);response.getWriter().println(value.getTextContent()+"<br/>");}}catch(javax.xml.xpath.XPathExpressionException|javax.xml.parsers.ParserConfigurationException|org.xml.sax.SAXExceptione){response.getWriter().println("Error parsing XPath input: '"+org.owasp.esapi.ESAPI.encoder().encodeForHTML(bar)+"'");thrownewServletException(e);}}// end doPostprivateclassTest{publicStringdoSomething(HttpServletRequestrequest,Stringparam)throwsServletException,IOException{Stringbar;Stringguess="ABC";charswitchTarget=guess.charAt(2);// Simple case statement that assigns param to bar on conditions 'A', 'C', or 'D'switch(switchTarget){case'A':bar=param;break;case'B':bar="bobs_your_uncle";break;case'C':case'D':bar=param;break;default:bar="bobs_your_uncle";break;}returnbar;}}// end innerclass Test}// end DataflowThruInnerClass
@WebServlet(value="/xpathi-00/BenchmarkTest01223")publicclassBenchmarkTest01223extendsHttpServlet{privatestaticfinallongserialVersionUID=1L;@OverridepublicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{doPost(request,response);}@OverridepublicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{response.setContentType("text/html;charset=UTF-8");Stringparam="";java.util.Enumeration<String>headers=request.getHeaders("BenchmarkTest01223");if(headers!=null&&headers.hasMoreElements()){param=headers.nextElement();// just grab first element}// URL Decode the header value since req.getHeaders() doesn't. Unlike req.getParameters().param=java.net.URLDecoder.decode(param,"UTF-8");Stringbar=newTest().doSomething(request,param);try{java.io.FileInputStreamfile=newjava.io.FileInputStream(org.owasp.benchmark.helpers.Utils.getFileFromClasspath("employees.xml",this.getClass().getClassLoader()));javax.xml.parsers.DocumentBuilderFactorybuilderFactory=javax.xml.parsers.DocumentBuilderFactory.newInstance();// Prevent XXEbuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);javax.xml.parsers.DocumentBuilderbuilder=builderFactory.newDocumentBuilder();org.w3c.dom.DocumentxmlDocument=builder.parse(file);javax.xml.xpath.XPathFactoryxpf=javax.xml.xpath.XPathFactory.newInstance();javax.xml.xpath.XPathxp=xpf.newXPath();Stringexpression="/Employees/Employee[@emplid='"+bar+"']";// ruleid: tainted-xpath-from-http-requestorg.w3c.dom.NodeListnodeList=(org.w3c.dom.NodeList)xp.compile(expression).evaluate(xmlDocument,javax.xml.xpath.XPathConstants.NODESET);response.getWriter().println("Your query results are: <br/>");for(inti=0;i<nodeList.getLength();i++){org.w3c.dom.Elementvalue=(org.w3c.dom.Element)nodeList.item(i);response.getWriter().println(value.getTextContent()+"<br/>");}}catch(javax.xml.xpath.XPathExpressionException|javax.xml.parsers.ParserConfigurationException|org.xml.sax.SAXExceptione){response.getWriter().println("Error parsing XPath input: '"+org.owasp.esapi.ESAPI.encoder().encodeForHTML(bar)+"'");thrownewServletException(e);}}// end doPostprivateclassTest{publicStringdoSomething(HttpServletRequestrequest,Stringparam)throwsServletException,IOException{Stringbar;Stringguess="ABC";charswitchTarget=guess.charAt(2);// Simple case statement that assigns param to bar on conditions 'A', 'C', or 'D'switch(switchTarget){case'A':bar=param;break;case'B':bar="bobs_your_uncle";break;case'C':case'D':bar=param;break;default:bar="bobs_your_uncle";break;}returnbar;}}// end innerclass Test}// end DataflowThruInnerClass
Compliant Code Examples
classClass{@OverridepublicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{response.setContentType("text/html;charset=UTF-8");javax.servlet.http.Cookie[]theCookies=request.getCookies();Stringparam="noCookieValueSupplied";if(theCookies!=null){for(javax.servlet.http.CookietheCookie:theCookies){if(theCookie.getName().equals("BenchmarkTest00118")){param=java.net.URLDecoder.decode(theCookie.getValue(),"UTF-8");break;}}}Stringbar;// Simple if statement that assigns constant to bar on true conditionintnum=86;if((7*42)-num>200)bar="This_should_always_happen";elsebar=param;try{java.io.FileInputStreamfile=newjava.io.FileInputStream(org.owasp.benchmark.helpers.Utils.getFileFromClasspath("employees.xml",this.getClass().getClassLoader()));javax.xml.parsers.DocumentBuilderFactorybuilderFactory=javax.xml.parsers.DocumentBuilderFactory.newInstance();// Prevent XXEbuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);javax.xml.parsers.DocumentBuilderbuilder=builderFactory.newDocumentBuilder();org.w3c.dom.DocumentxmlDocument=builder.parse(file);javax.xml.xpath.XPathFactoryxpf=javax.xml.xpath.XPathFactory.newInstance();javax.xml.xpath.XPathxp=xpf.newXPath();Stringexpression="/Employees/Employee[@emplid='"+bar+"']";Stringresult=xp.evaluate(expression,xmlDocument);response.getWriter().println("Your query results are: "+result+"<br/>");}catch(javax.xml.xpath.XPathExpressionException|javax.xml.parsers.ParserConfigurationException|org.xml.sax.SAXExceptione){response.getWriter().println("Error parsing XPath input: '"+org.owasp.esapi.ESAPI.encoder().encodeForHTML(bar)+"'");thrownewServletException(e);}}}
classTest{@OverridepublicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{response.setContentType("text/html;charset=UTF-8");javax.servlet.http.Cookie[]theCookies=request.getCookies();Stringparam="noCookieValueSupplied";if(theCookies!=null){for(javax.servlet.http.CookietheCookie:theCookies){if(theCookie.getName().equals("BenchmarkTest00116")){param=java.net.URLDecoder.decode(theCookie.getValue(),"UTF-8");break;}}}Stringbar="safe!";java.util.HashMap<String,Object>map51005=newjava.util.HashMap<String,Object>();map51005.put("keyA-51005","a_Value");// put some stuff in the collectionmap51005.put("keyB-51005",param);// put it in a collectionmap51005.put("keyC","another_Value");// put some stuff in the collectionbar=(String)map51005.get("keyB-51005");// get it back outbar=(String)map51005.get("keyA-51005");// get safe value back outtry{java.io.FileInputStreamfile=newjava.io.FileInputStream(org.owasp.benchmark.helpers.Utils.getFileFromClasspath("employees.xml",this.getClass().getClassLoader()));javax.xml.parsers.DocumentBuilderFactorybuilderFactory=javax.xml.parsers.DocumentBuilderFactory.newInstance();// Prevent XXEbuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);javax.xml.parsers.DocumentBuilderbuilder=builderFactory.newDocumentBuilder();org.w3c.dom.DocumentxmlDocument=builder.parse(file);javax.xml.xpath.XPathFactoryxpf=javax.xml.xpath.XPathFactory.newInstance();javax.xml.xpath.XPathxp=xpf.newXPath();Stringexpression="/Employees/Employee[@emplid='"+bar+"']";org.w3c.dom.NodeListnodeList=(org.w3c.dom.NodeList)xp.compile(expression).evaluate(xmlDocument,javax.xml.xpath.XPathConstants.NODESET);response.getWriter().println("Your query results are: <br/>");for(inti=0;i<nodeList.getLength();i++){org.w3c.dom.Elementvalue=(org.w3c.dom.Element)nodeList.item(i);response.getWriter().println(value.getTextContent()+"<br/>");}}catch(javax.xml.xpath.XPathExpressionException|javax.xml.parsers.ParserConfigurationException|org.xml.sax.SAXExceptione){response.getWriter().println("Error parsing XPath input: '"+org.owasp.esapi.ESAPI.encoder().encodeForHTML(bar)+"'");thrownewServletException(e);}}}
@WebServlet(value="/xpathi-00/BenchmarkTest00207")publicclassBenchmarkTest00207extendsHttpServlet{privatestaticfinallongserialVersionUID=1L;@OverridepublicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{doPost(request,response);}@OverridepublicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{response.setContentType("text/html;charset=UTF-8");Stringparam="";if(request.getHeader("BenchmarkTest00207")!=null){param=request.getHeader("BenchmarkTest00207");}// URL Decode the header value since req.getHeader() doesn't. Unlike req.getParameter().param=java.net.URLDecoder.decode(param,"UTF-8");Stringbar="";if(param!=null){bar=newString(org.apache.commons.codec.binary.Base64.decodeBase64(org.apache.commons.codec.binary.Base64.encodeBase64(param.getBytes())));}try{java.io.FileInputStreamfile=newjava.io.FileInputStream(org.owasp.benchmark.helpers.Utils.getFileFromClasspath("employees.xml",this.getClass().getClassLoader()));javax.xml.parsers.DocumentBuilderFactorybuilderFactory=javax.xml.parsers.DocumentBuilderFactory.newInstance();// Prevent XXEbuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);javax.xml.parsers.DocumentBuilderbuilder=builderFactory.newDocumentBuilder();org.w3c.dom.DocumentxmlDocument=builder.parse(file);javax.xml.xpath.XPathFactoryxpf=javax.xml.xpath.XPathFactory.newInstance();javax.xml.xpath.XPathxp=xpf.newXPath();Stringexpression="/Employees/Employee[@emplid='1234']";Stringresult=xp.evaluate(expression,xmlDocument);response.getWriter().println("Your query results are: "+result+"<br/>");}catch(javax.xml.xpath.XPathExpressionException|javax.xml.parsers.ParserConfigurationException|org.xml.sax.SAXExceptione){response.getWriter().println("Error parsing XPath input: '"+org.owasp.esapi.ESAPI.encoder().encodeForHTML(bar)+"'");thrownewServletException(e);}}}
Seamless integrations. Try Datadog Code Analysis
Datadog Code Analysis
Try this rule and analyze your code with Datadog Code Analysis
How to use this rule
1
2
rulesets:- java-security # Rules to enforce Java security.
Create a static-analysis.datadog.yml with the content above at the root of your repository
Use our free IDE Plugins or add Code Analysis scans to your CI pipelines