mirror of
https://github.com/github/codeql.git
synced 2025-12-21 19:26:31 +01:00
Merge pull request #6097 from atorralba/atorralba/promote-xslt-injection
Java: Promote XSLT Injection from experimental
This commit is contained in:
2
java/change-notes/2021-06-16-xslt-injection-query.md
Normal file
2
java/change-notes/2021-06-16-xslt-injection-query.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
lgtm,codescanning
|
||||||
|
* The query "XSLT transformation with user-controlled stylesheet" (`java/xslt-injection`) has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @ggolawski](https://github.com/github/codeql/pull/3363).
|
||||||
@@ -110,6 +110,7 @@ private module Frameworks {
|
|||||||
private import semmle.code.java.security.MvelInjection
|
private import semmle.code.java.security.MvelInjection
|
||||||
private import semmle.code.java.security.OgnlInjection
|
private import semmle.code.java.security.OgnlInjection
|
||||||
private import semmle.code.java.security.XPath
|
private import semmle.code.java.security.XPath
|
||||||
|
private import semmle.code.java.security.XsltInjection
|
||||||
private import semmle.code.java.frameworks.android.Android
|
private import semmle.code.java.frameworks.android.Android
|
||||||
private import semmle.code.java.frameworks.android.SQLite
|
private import semmle.code.java.frameworks.android.SQLite
|
||||||
private import semmle.code.java.frameworks.Jdbc
|
private import semmle.code.java.frameworks.Jdbc
|
||||||
|
|||||||
248
java/ql/lib/semmle/code/java/security/XsltInjection.qll
Normal file
248
java/ql/lib/semmle/code/java/security/XsltInjection.qll
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
/** Provides classes to reason about XSLT injection vulnerabilities. */
|
||||||
|
|
||||||
|
import java
|
||||||
|
import semmle.code.java.dataflow.DataFlow
|
||||||
|
import semmle.code.java.dataflow.ExternalFlow
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data flow sink for unvalidated user input that is used in XSLT transformation.
|
||||||
|
* Extend this class to add your own XSLT Injection sinks.
|
||||||
|
*/
|
||||||
|
abstract class XsltInjectionSink extends DataFlow::Node { }
|
||||||
|
|
||||||
|
/** A default sink representing methods susceptible to XSLT Injection attacks. */
|
||||||
|
private class DefaultXsltInjectionSink extends XsltInjectionSink {
|
||||||
|
DefaultXsltInjectionSink() { sinkNode(this, "xslt") }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DefaultXsltInjectionSinkModel extends SinkModelCsv {
|
||||||
|
override predicate row(string row) {
|
||||||
|
row =
|
||||||
|
[
|
||||||
|
"javax.xml.transform;Transformer;false;transform;;;Argument[-1];xslt",
|
||||||
|
"net.sf.saxon.s9api;XsltTransformer;false;transform;;;Argument[-1];xslt",
|
||||||
|
"net.sf.saxon.s9api;Xslt30Transformer;false;transform;;;Argument[-1];xslt",
|
||||||
|
"net.sf.saxon.s9api;Xslt30Transformer;false;applyTemplates;;;Argument[-1];xslt",
|
||||||
|
"net.sf.saxon.s9api;Xslt30Transformer;false;callFunction;;;Argument[-1];xslt",
|
||||||
|
"net.sf.saxon.s9api;Xslt30Transformer;false;callTemplate;;;Argument[-1];xslt"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A unit class for adding additional taint steps.
|
||||||
|
*
|
||||||
|
* Extend this class to add additional taint steps that should apply to the `XsltInjectionFlowConfig`.
|
||||||
|
*/
|
||||||
|
class XsltInjectionAdditionalTaintStep extends Unit {
|
||||||
|
/**
|
||||||
|
* Holds if the step from `node1` to `node2` should be considered a taint
|
||||||
|
* step for the `XsltInjectionFlowConfig` configuration.
|
||||||
|
*/
|
||||||
|
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A set of additional taint steps to consider when taint tracking XSLT related data flows. */
|
||||||
|
private class DefaultXsltInjectionAdditionalTaintStep extends XsltInjectionAdditionalTaintStep {
|
||||||
|
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
|
||||||
|
xmlStreamReaderStep(node1, node2) or
|
||||||
|
xmlEventReaderStep(node1, node2) or
|
||||||
|
staxSourceStep(node1, node2) or
|
||||||
|
documentBuilderStep(node1, node2) or
|
||||||
|
domSourceStep(node1, node2) or
|
||||||
|
newTransformerFromTemplatesStep(node1, node2) or
|
||||||
|
xsltCompilerStep(node1, node2) or
|
||||||
|
xsltExecutableStep(node1, node2) or
|
||||||
|
xsltPackageStep(node1, node2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `InputStream` or `Reader` and
|
||||||
|
* `XMLStreamReader`, i.e. `XMLInputFactory.createXMLStreamReader(tainted)`.
|
||||||
|
*/
|
||||||
|
private predicate xmlStreamReaderStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||||
|
exists(XmlInputFactoryStreamReader xmlStreamReader |
|
||||||
|
if xmlStreamReader.getMethod().getParameterType(0) instanceof TypeString
|
||||||
|
then n1.asExpr() = xmlStreamReader.getArgument(1)
|
||||||
|
else n1.asExpr() = xmlStreamReader.getArgument(0)
|
||||||
|
|
|
||||||
|
n2.asExpr() = xmlStreamReader
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `InputStream` or `Reader` and
|
||||||
|
* `XMLEventReader`, i.e. `XMLInputFactory.createXMLEventReader(tainted)`.
|
||||||
|
*/
|
||||||
|
private predicate xmlEventReaderStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||||
|
exists(XmlInputFactoryEventReader xmlEventReader |
|
||||||
|
if xmlEventReader.getMethod().getParameterType(0) instanceof TypeString
|
||||||
|
then n1.asExpr() = xmlEventReader.getArgument(1)
|
||||||
|
else n1.asExpr() = xmlEventReader.getArgument(0)
|
||||||
|
|
|
||||||
|
n2.asExpr() = xmlEventReader
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `XMLStreamReader` or
|
||||||
|
* `XMLEventReader` and `StAXSource`, i.e. `new StAXSource(tainted)`.
|
||||||
|
*/
|
||||||
|
private predicate staxSourceStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||||
|
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeStAXSource |
|
||||||
|
n1.asExpr() = cc.getAnArgument() and
|
||||||
|
n2.asExpr() = cc
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `InputStream` and `Document`,
|
||||||
|
* i.e. `DocumentBuilder.parse(tainted)`.
|
||||||
|
*/
|
||||||
|
private predicate documentBuilderStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||||
|
exists(DocumentBuilderParse documentBuilder |
|
||||||
|
n1.asExpr() = documentBuilder.getArgument(0) and
|
||||||
|
n2.asExpr() = documentBuilder
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `Document` and `DOMSource`, i.e.
|
||||||
|
* `new DOMSource(tainted)`.
|
||||||
|
*/
|
||||||
|
private predicate domSourceStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||||
|
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeDOMSource |
|
||||||
|
n1.asExpr() = cc.getAnArgument() and
|
||||||
|
n2.asExpr() = cc
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `Templates` and `Transformer`,
|
||||||
|
* i.e. `tainted.newTransformer()`.
|
||||||
|
*/
|
||||||
|
private predicate newTransformerFromTemplatesStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||||
|
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
||||||
|
n1.asExpr() = ma.getQualifier() and
|
||||||
|
n2.asExpr() = ma and
|
||||||
|
m.getDeclaringType() instanceof TypeTemplates and
|
||||||
|
m.hasName("newTransformer")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `Source` or `URI` and
|
||||||
|
* `XsltExecutable` or `XsltPackage`, i.e. `XsltCompiler.compile(tainted)` or
|
||||||
|
* `XsltCompiler.loadExecutablePackage(tainted)` or `XsltCompiler.compilePackage(tainted)` or
|
||||||
|
* `XsltCompiler.loadLibraryPackage(tainted)`.
|
||||||
|
*/
|
||||||
|
private predicate xsltCompilerStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||||
|
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
||||||
|
n1.asExpr() = ma.getArgument(0) and
|
||||||
|
n2.asExpr() = ma and
|
||||||
|
m.getDeclaringType() instanceof TypeXsltCompiler and
|
||||||
|
m.hasName(["compile", "loadExecutablePackage", "compilePackage", "loadLibraryPackage"])
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `XsltExecutable` and
|
||||||
|
* `XsltTransformer` or `Xslt30Transformer`, i.e. `XsltExecutable.load()` or
|
||||||
|
* `XsltExecutable.load30()`.
|
||||||
|
*/
|
||||||
|
private predicate xsltExecutableStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||||
|
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
||||||
|
n1.asExpr() = ma.getQualifier() and
|
||||||
|
n2.asExpr() = ma and
|
||||||
|
m.getDeclaringType() instanceof TypeXsltExecutable and
|
||||||
|
m.hasName(["load", "load30"])
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `XsltPackage` and
|
||||||
|
* `XsltExecutable`, i.e. `XsltPackage.link()`.
|
||||||
|
*/
|
||||||
|
private predicate xsltPackageStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||||
|
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
||||||
|
n1.asExpr() = ma.getQualifier() and
|
||||||
|
n2.asExpr() = ma and
|
||||||
|
m.getDeclaringType() instanceof TypeXsltPackage and
|
||||||
|
m.hasName("link")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The class `javax.xml.transform.stax.StAXSource`. */
|
||||||
|
private class TypeStAXSource extends Class {
|
||||||
|
TypeStAXSource() { this.hasQualifiedName("javax.xml.transform.stax", "StAXSource") }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The class `javax.xml.transform.dom.DOMSource`. */
|
||||||
|
private class TypeDOMSource extends Class {
|
||||||
|
TypeDOMSource() { this.hasQualifiedName("javax.xml.transform.dom", "DOMSource") }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The interface `javax.xml.transform.Templates`. */
|
||||||
|
private class TypeTemplates extends Interface {
|
||||||
|
TypeTemplates() { this.hasQualifiedName("javax.xml.transform", "Templates") }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The class `net.sf.saxon.s9api.XsltCompiler`. */
|
||||||
|
private class TypeXsltCompiler extends Class {
|
||||||
|
TypeXsltCompiler() { this.hasQualifiedName("net.sf.saxon.s9api", "XsltCompiler") }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The class `net.sf.saxon.s9api.XsltExecutable`. */
|
||||||
|
private class TypeXsltExecutable extends Class {
|
||||||
|
TypeXsltExecutable() { this.hasQualifiedName("net.sf.saxon.s9api", "XsltExecutable") }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The class `net.sf.saxon.s9api.XsltPackage`. */
|
||||||
|
private class TypeXsltPackage extends Class {
|
||||||
|
TypeXsltPackage() { this.hasQualifiedName("net.sf.saxon.s9api", "XsltPackage") }
|
||||||
|
}
|
||||||
|
|
||||||
|
// XmlParsers classes
|
||||||
|
/** A call to `DocumentBuilder.parse`. */
|
||||||
|
private class DocumentBuilderParse extends MethodAccess {
|
||||||
|
DocumentBuilderParse() {
|
||||||
|
exists(Method m |
|
||||||
|
this.getMethod() = m and
|
||||||
|
m.getDeclaringType() instanceof DocumentBuilder and
|
||||||
|
m.hasName("parse")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The class `javax.xml.parsers.DocumentBuilder`. */
|
||||||
|
private class DocumentBuilder extends RefType {
|
||||||
|
DocumentBuilder() { this.hasQualifiedName("javax.xml.parsers", "DocumentBuilder") }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A call to `XMLInputFactory.createXMLStreamReader`. */
|
||||||
|
private class XmlInputFactoryStreamReader extends MethodAccess {
|
||||||
|
XmlInputFactoryStreamReader() {
|
||||||
|
exists(Method m |
|
||||||
|
this.getMethod() = m and
|
||||||
|
m.getDeclaringType() instanceof XmlInputFactory and
|
||||||
|
m.hasName("createXMLStreamReader")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A call to `XMLInputFactory.createEventReader`. */
|
||||||
|
private class XmlInputFactoryEventReader extends MethodAccess {
|
||||||
|
XmlInputFactoryEventReader() {
|
||||||
|
exists(Method m |
|
||||||
|
this.getMethod() = m and
|
||||||
|
m.getDeclaringType() instanceof XmlInputFactory and
|
||||||
|
m.hasName("createXMLEventReader")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The class `javax.xml.stream.XMLInputFactory`. */
|
||||||
|
private class XmlInputFactory extends RefType {
|
||||||
|
XmlInputFactory() { this.hasQualifiedName("javax.xml.stream", "XMLInputFactory") }
|
||||||
|
}
|
||||||
90
java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll
Normal file
90
java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/** Provides taint tracking configurations to be used in XSLT injection queries. */
|
||||||
|
|
||||||
|
import java
|
||||||
|
import semmle.code.java.dataflow.FlowSources
|
||||||
|
import semmle.code.java.dataflow.TaintTracking
|
||||||
|
import semmle.code.java.security.XmlParsers
|
||||||
|
import semmle.code.java.security.XsltInjection
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A taint-tracking configuration for unvalidated user input that is used in XSLT transformation.
|
||||||
|
*/
|
||||||
|
class XsltInjectionFlowConfig extends TaintTracking::Configuration {
|
||||||
|
XsltInjectionFlowConfig() { this = "XsltInjectionFlowConfig" }
|
||||||
|
|
||||||
|
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||||
|
|
||||||
|
override predicate isSink(DataFlow::Node sink) { sink instanceof XsltInjectionSink }
|
||||||
|
|
||||||
|
override predicate isSanitizer(DataFlow::Node node) {
|
||||||
|
node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||||
|
any(XsltInjectionAdditionalTaintStep c).step(node1, node2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of additional taint steps to consider when taint tracking XSLT related data flows.
|
||||||
|
* These steps use data flow logic themselves.
|
||||||
|
*/
|
||||||
|
private class DataFlowXsltInjectionAdditionalTaintStep extends XsltInjectionAdditionalTaintStep {
|
||||||
|
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
|
||||||
|
newTransformerOrTemplatesStep(node1, node2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `n1` to `n2` is a dataflow step that converts between `Source` and `Transformer` or
|
||||||
|
* `Templates`, i.e. `TransformerFactory.newTransformer(tainted)` or
|
||||||
|
* `TransformerFactory.newTemplates(tainted)`.
|
||||||
|
*/
|
||||||
|
private predicate newTransformerOrTemplatesStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||||
|
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
||||||
|
n1.asExpr() = ma.getAnArgument() and
|
||||||
|
n2.asExpr() = ma and
|
||||||
|
m.getDeclaringType() instanceof TransformerFactory and
|
||||||
|
m.hasName(["newTransformer", "newTemplates"]) and
|
||||||
|
not exists(TransformerFactoryWithSecureProcessingFeatureFlowConfig conf |
|
||||||
|
conf.hasFlowToExpr(ma.getQualifier())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data flow configuration for secure processing feature that is enabled on `TransformerFactory`.
|
||||||
|
*/
|
||||||
|
private class TransformerFactoryWithSecureProcessingFeatureFlowConfig extends DataFlow2::Configuration {
|
||||||
|
TransformerFactoryWithSecureProcessingFeatureFlowConfig() {
|
||||||
|
this = "TransformerFactoryWithSecureProcessingFeatureFlowConfig"
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate isSource(DataFlow::Node src) {
|
||||||
|
exists(Variable v | v = src.asExpr().(VarAccess).getVariable() |
|
||||||
|
exists(TransformerFactoryFeatureConfig config | config.getQualifier() = v.getAnAccess() |
|
||||||
|
config.enables(configSecureProcessing())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate isSink(DataFlow::Node sink) {
|
||||||
|
exists(MethodAccess ma |
|
||||||
|
sink.asExpr() = ma.getQualifier() and
|
||||||
|
ma.getMethod().getDeclaringType() instanceof TransformerFactory
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override int fieldFlowBranchLimit() { result = 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A `ParserConfig` specific to `TransformerFactory`. */
|
||||||
|
private class TransformerFactoryFeatureConfig extends ParserConfig {
|
||||||
|
TransformerFactoryFeatureConfig() {
|
||||||
|
exists(Method m |
|
||||||
|
m = this.getMethod() and
|
||||||
|
m.getDeclaringType() instanceof TransformerFactory and
|
||||||
|
m.hasName("setFeature")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,12 +4,12 @@
|
|||||||
<qhelp>
|
<qhelp>
|
||||||
<overview>
|
<overview>
|
||||||
<p>XSLT (Extensible Stylesheet Language Transformations) is a language for transforming XML
|
<p>XSLT (Extensible Stylesheet Language Transformations) is a language for transforming XML
|
||||||
documents into other XML documents or other formats. Processing of unvalidated XSLT stylesheet can
|
documents into other XML documents or other formats. Processing unvalidated XSLT stylesheets can
|
||||||
let attacker to read arbitrary files from the filesystem or to execute arbitrary code.</p>
|
allow attackers to read arbitrary files from the filesystem or to execute arbitrary code.</p>
|
||||||
</overview>
|
</overview>
|
||||||
|
|
||||||
<recommendation>
|
<recommendation>
|
||||||
<p>The general recommendation is to not process untrusted XSLT stylesheets. If user provided
|
<p>The general recommendation is to not process untrusted XSLT stylesheets. If user-provided
|
||||||
stylesheets must be processed, enable the secure processing mode.</p>
|
stylesheets must be processed, enable the secure processing mode.</p>
|
||||||
</recommendation>
|
</recommendation>
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ stylesheets must be processed, enable the secure processing mode.</p>
|
|||||||
<p>In the following examples, the code accepts an XSLT stylesheet from the user and processes it.
|
<p>In the following examples, the code accepts an XSLT stylesheet from the user and processes it.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>In the first example, the user provided XSLT stylesheet is parsed and processed.</p>
|
<p>In the first example, the user-provided XSLT stylesheet is parsed and processed.</p>
|
||||||
|
|
||||||
<p>In the second example, secure processing mode is enabled.</p>
|
<p>In the second example, secure processing mode is enabled.</p>
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* @name XSLT transformation with user-controlled stylesheet
|
* @name XSLT transformation with user-controlled stylesheet
|
||||||
* @description Doing an XSLT transformation with user-controlled stylesheet can lead to
|
* @description Performing an XSLT transformation with user-controlled stylesheets can lead to
|
||||||
* information disclosure or execution of arbitrary code.
|
* information disclosure or execution of arbitrary code.
|
||||||
* @kind path-problem
|
* @kind path-problem
|
||||||
* @problem.severity error
|
* @problem.severity error
|
||||||
@@ -11,8 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import java
|
import java
|
||||||
import semmle.code.java.dataflow.FlowSources
|
import semmle.code.java.security.XsltInjectionQuery
|
||||||
import XsltInjectionLib
|
|
||||||
import DataFlow::PathGraph
|
import DataFlow::PathGraph
|
||||||
|
|
||||||
from DataFlow::PathNode source, DataFlow::PathNode sink, XsltInjectionFlowConfig conf
|
from DataFlow::PathNode source, DataFlow::PathNode sink, XsltInjectionFlowConfig conf
|
||||||
@@ -1,288 +0,0 @@
|
|||||||
import java
|
|
||||||
import semmle.code.java.dataflow.FlowSources
|
|
||||||
import semmle.code.java.security.XmlParsers
|
|
||||||
import DataFlow
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A taint-tracking configuration for unvalidated user input that is used in XSLT transformation.
|
|
||||||
*/
|
|
||||||
class XsltInjectionFlowConfig extends TaintTracking::Configuration {
|
|
||||||
XsltInjectionFlowConfig() { this = "XsltInjectionFlowConfig" }
|
|
||||||
|
|
||||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
|
||||||
|
|
||||||
override predicate isSink(DataFlow::Node sink) { sink instanceof XsltInjectionSink }
|
|
||||||
|
|
||||||
override predicate isSanitizer(DataFlow::Node node) {
|
|
||||||
node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType
|
|
||||||
}
|
|
||||||
|
|
||||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
|
||||||
xmlStreamReaderStep(node1, node2) or
|
|
||||||
xmlEventReaderStep(node1, node2) or
|
|
||||||
staxSourceStep(node1, node2) or
|
|
||||||
documentBuilderStep(node1, node2) or
|
|
||||||
domSourceStep(node1, node2) or
|
|
||||||
newTransformerOrTemplatesStep(node1, node2) or
|
|
||||||
newTransformerFromTemplatesStep(node1, node2) or
|
|
||||||
xsltCompilerStep(node1, node2) or
|
|
||||||
xsltExecutableStep(node1, node2) or
|
|
||||||
xsltPackageStep(node1, node2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The class `javax.xml.transform.stax.StAXSource`. */
|
|
||||||
class TypeStAXSource extends Class {
|
|
||||||
TypeStAXSource() { this.hasQualifiedName("javax.xml.transform.stax", "StAXSource") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The class `javax.xml.transform.dom.DOMSource`. */
|
|
||||||
class TypeDOMSource extends Class {
|
|
||||||
TypeDOMSource() { this.hasQualifiedName("javax.xml.transform.dom", "DOMSource") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The interface `javax.xml.transform.Templates`. */
|
|
||||||
class TypeTemplates extends Interface {
|
|
||||||
TypeTemplates() { this.hasQualifiedName("javax.xml.transform", "Templates") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The method `net.sf.saxon.s9api.XsltTransformer.transform`. */
|
|
||||||
class XsltTransformerTransformMethod extends Method {
|
|
||||||
XsltTransformerTransformMethod() {
|
|
||||||
this.getDeclaringType().hasQualifiedName("net.sf.saxon.s9api", "XsltTransformer") and
|
|
||||||
this.hasName("transform")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The method `net.sf.saxon.s9api.Xslt30Transformer.transform`. */
|
|
||||||
class Xslt30TransformerTransformMethod extends Method {
|
|
||||||
Xslt30TransformerTransformMethod() {
|
|
||||||
this.getDeclaringType().hasQualifiedName("net.sf.saxon.s9api", "Xslt30Transformer") and
|
|
||||||
this.hasName("transform")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The method `net.sf.saxon.s9api.Xslt30Transformer.applyTemplates`. */
|
|
||||||
class Xslt30TransformerApplyTemplatesMethod extends Method {
|
|
||||||
Xslt30TransformerApplyTemplatesMethod() {
|
|
||||||
this.getDeclaringType().hasQualifiedName("net.sf.saxon.s9api", "Xslt30Transformer") and
|
|
||||||
this.hasName("applyTemplates")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The method `net.sf.saxon.s9api.Xslt30Transformer.callFunction`. */
|
|
||||||
class Xslt30TransformerCallFunctionMethod extends Method {
|
|
||||||
Xslt30TransformerCallFunctionMethod() {
|
|
||||||
this.getDeclaringType().hasQualifiedName("net.sf.saxon.s9api", "Xslt30Transformer") and
|
|
||||||
this.hasName("callFunction")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The method `net.sf.saxon.s9api.Xslt30Transformer.callTemplate`. */
|
|
||||||
class Xslt30TransformerCallTemplateMethod extends Method {
|
|
||||||
Xslt30TransformerCallTemplateMethod() {
|
|
||||||
this.getDeclaringType().hasQualifiedName("net.sf.saxon.s9api", "Xslt30Transformer") and
|
|
||||||
this.hasName("callTemplate")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The class `net.sf.saxon.s9api.XsltCompiler`. */
|
|
||||||
class TypeXsltCompiler extends Class {
|
|
||||||
TypeXsltCompiler() { this.hasQualifiedName("net.sf.saxon.s9api", "XsltCompiler") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The class `net.sf.saxon.s9api.XsltExecutable`. */
|
|
||||||
class TypeXsltExecutable extends Class {
|
|
||||||
TypeXsltExecutable() { this.hasQualifiedName("net.sf.saxon.s9api", "XsltExecutable") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The class `net.sf.saxon.s9api.XsltPackage`. */
|
|
||||||
class TypeXsltPackage extends Class {
|
|
||||||
TypeXsltPackage() { this.hasQualifiedName("net.sf.saxon.s9api", "XsltPackage") }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A data flow sink for unvalidated user input that is used in XSLT transformation. */
|
|
||||||
class XsltInjectionSink extends DataFlow::ExprNode {
|
|
||||||
XsltInjectionSink() {
|
|
||||||
exists(MethodAccess ma, Method m | m = ma.getMethod() and ma.getQualifier() = this.getExpr() |
|
|
||||||
ma instanceof TransformerTransform or
|
|
||||||
m instanceof XsltTransformerTransformMethod or
|
|
||||||
m instanceof Xslt30TransformerTransformMethod or
|
|
||||||
m instanceof Xslt30TransformerApplyTemplatesMethod or
|
|
||||||
m instanceof Xslt30TransformerCallFunctionMethod or
|
|
||||||
m instanceof Xslt30TransformerCallTemplateMethod
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `n1` to `n2` is a dataflow step that converts between `InputStream` or `Reader` and
|
|
||||||
* `XMLStreamReader`, i.e. `XMLInputFactory.createXMLStreamReader(tainted)`.
|
|
||||||
*/
|
|
||||||
predicate xmlStreamReaderStep(ExprNode n1, ExprNode n2) {
|
|
||||||
exists(XmlInputFactoryStreamReader xmlStreamReader |
|
|
||||||
n1.asExpr() = xmlStreamReader.getSink() and
|
|
||||||
n2.asExpr() = xmlStreamReader
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `n1` to `n2` is a dataflow step that converts between `InputStream` or `Reader` and
|
|
||||||
* `XMLEventReader`, i.e. `XMLInputFactory.createXMLEventReader(tainted)`.
|
|
||||||
*/
|
|
||||||
predicate xmlEventReaderStep(ExprNode n1, ExprNode n2) {
|
|
||||||
exists(XmlInputFactoryEventReader xmlEventReader |
|
|
||||||
n1.asExpr() = xmlEventReader.getSink() and
|
|
||||||
n2.asExpr() = xmlEventReader
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `n1` to `n2` is a dataflow step that converts between `XMLStreamReader` or
|
|
||||||
* `XMLEventReader` and `StAXSource`, i.e. `new StAXSource(tainted)`.
|
|
||||||
*/
|
|
||||||
predicate staxSourceStep(ExprNode n1, ExprNode n2) {
|
|
||||||
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeStAXSource |
|
|
||||||
n1.asExpr() = cc.getAnArgument() and
|
|
||||||
n2.asExpr() = cc
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `n1` to `n2` is a dataflow step that converts between `InputStream` and `Document`,
|
|
||||||
* i.e. `DocumentBuilder.parse(tainted)`.
|
|
||||||
*/
|
|
||||||
predicate documentBuilderStep(ExprNode n1, ExprNode n2) {
|
|
||||||
exists(DocumentBuilderParse documentBuilder |
|
|
||||||
n1.asExpr() = documentBuilder.getSink() and
|
|
||||||
n2.asExpr() = documentBuilder
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `n1` to `n2` is a dataflow step that converts between `Document` and `DOMSource`, i.e.
|
|
||||||
* `new DOMSource(tainted)`.
|
|
||||||
*/
|
|
||||||
predicate domSourceStep(ExprNode n1, ExprNode n2) {
|
|
||||||
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeDOMSource |
|
|
||||||
n1.asExpr() = cc.getAnArgument() and
|
|
||||||
n2.asExpr() = cc
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A data flow configuration for secure processing feature that is enabled on `TransformerFactory`.
|
|
||||||
*/
|
|
||||||
private class TransformerFactoryWithSecureProcessingFeatureFlowConfig extends DataFlow2::Configuration {
|
|
||||||
TransformerFactoryWithSecureProcessingFeatureFlowConfig() {
|
|
||||||
this = "TransformerFactoryWithSecureProcessingFeatureFlowConfig"
|
|
||||||
}
|
|
||||||
|
|
||||||
override predicate isSource(DataFlow::Node src) {
|
|
||||||
exists(Variable v | v = src.asExpr().(VarAccess).getVariable() |
|
|
||||||
exists(TransformerFactoryFeatureConfig config | config.getQualifier() = v.getAnAccess() |
|
|
||||||
config.enables(configSecureProcessing())
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override predicate isSink(DataFlow::Node sink) {
|
|
||||||
exists(MethodAccess ma |
|
|
||||||
sink.asExpr() = ma.getQualifier() and
|
|
||||||
ma.getMethod().getDeclaringType() instanceof TransformerFactory
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override int fieldFlowBranchLimit() { result = 0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A `ParserConfig` specific to `TransformerFactory`. */
|
|
||||||
private class TransformerFactoryFeatureConfig extends ParserConfig {
|
|
||||||
TransformerFactoryFeatureConfig() {
|
|
||||||
exists(Method m |
|
|
||||||
m = this.getMethod() and
|
|
||||||
m.getDeclaringType() instanceof TransformerFactory and
|
|
||||||
m.hasName("setFeature")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `n1` to `n2` is a dataflow step that converts between `Source` and `Transformer` or
|
|
||||||
* `Templates`, i.e. `TransformerFactory.newTransformer(tainted)` or
|
|
||||||
* `TransformerFactory.newTemplates(tainted)`.
|
|
||||||
*/
|
|
||||||
predicate newTransformerOrTemplatesStep(ExprNode n1, ExprNode n2) {
|
|
||||||
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
|
||||||
n1.asExpr() = ma.getAnArgument() and
|
|
||||||
n2.asExpr() = ma and
|
|
||||||
(
|
|
||||||
m.getDeclaringType() instanceof TransformerFactory and m.hasName("newTransformer")
|
|
||||||
or
|
|
||||||
m.getDeclaringType() instanceof TransformerFactory and m.hasName("newTemplates")
|
|
||||||
) and
|
|
||||||
not exists(TransformerFactoryWithSecureProcessingFeatureFlowConfig conf |
|
|
||||||
conf.hasFlowToExpr(ma.getQualifier())
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `n1` to `n2` is a dataflow step that converts between `Templates` and `Transformer`,
|
|
||||||
* i.e. `tainted.newTransformer()`.
|
|
||||||
*/
|
|
||||||
predicate newTransformerFromTemplatesStep(ExprNode n1, ExprNode n2) {
|
|
||||||
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
|
||||||
n1.asExpr() = ma.getQualifier() and
|
|
||||||
n2.asExpr() = ma and
|
|
||||||
m.getDeclaringType() instanceof TypeTemplates and
|
|
||||||
m.hasName("newTransformer")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `n1` to `n2` is a dataflow step that converts between `Source` or `URI` and
|
|
||||||
* `XsltExecutable` or `XsltPackage`, i.e. `XsltCompiler.compile(tainted)` or
|
|
||||||
* `XsltCompiler.loadExecutablePackage(tainted)` or `XsltCompiler.compilePackage(tainted)` or
|
|
||||||
* `XsltCompiler.loadLibraryPackage(tainted)`.
|
|
||||||
*/
|
|
||||||
predicate xsltCompilerStep(ExprNode n1, ExprNode n2) {
|
|
||||||
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
|
||||||
n1.asExpr() = ma.getArgument(0) and
|
|
||||||
n2.asExpr() = ma and
|
|
||||||
m.getDeclaringType() instanceof TypeXsltCompiler and
|
|
||||||
(
|
|
||||||
m.hasName("compile") or
|
|
||||||
m.hasName("loadExecutablePackage") or
|
|
||||||
m.hasName("compilePackage") or
|
|
||||||
m.hasName("loadLibraryPackage")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `n1` to `n2` is a dataflow step that converts between `XsltExecutable` and
|
|
||||||
* `XsltTransformer` or `Xslt30Transformer`, i.e. `XsltExecutable.load()` or
|
|
||||||
* `XsltExecutable.load30()`.
|
|
||||||
*/
|
|
||||||
predicate xsltExecutableStep(ExprNode n1, ExprNode n2) {
|
|
||||||
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
|
||||||
n1.asExpr() = ma.getQualifier() and
|
|
||||||
n2.asExpr() = ma and
|
|
||||||
m.getDeclaringType() instanceof TypeXsltExecutable and
|
|
||||||
(m.hasName("load") or m.hasName("load30"))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `n1` to `n2` is a dataflow step that converts between `XsltPackage` and
|
|
||||||
* `XsltExecutable`, i.e. `XsltPackage.link()`.
|
|
||||||
*/
|
|
||||||
predicate xsltPackageStep(ExprNode n1, ExprNode n2) {
|
|
||||||
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
|
||||||
n1.asExpr() = ma.getQualifier() and
|
|
||||||
n2.asExpr() = ma and
|
|
||||||
m.getDeclaringType() instanceof TypeXsltPackage and
|
|
||||||
m.hasName("link")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
edges
|
|
||||||
| XsltInjection.java:30:27:30:67 | new StreamSource(...) : StreamSource | XsltInjection.java:31:5:31:59 | newTransformer(...) |
|
|
||||||
| XsltInjection.java:30:44:30:66 | getInputStream(...) : InputStream | XsltInjection.java:30:27:30:67 | new StreamSource(...) : StreamSource |
|
|
||||||
| XsltInjection.java:35:27:35:90 | new StreamSource(...) : StreamSource | XsltInjection.java:36:5:36:74 | newTransformer(...) |
|
|
||||||
| XsltInjection.java:35:44:35:89 | new InputStreamReader(...) : InputStreamReader | XsltInjection.java:35:27:35:90 | new StreamSource(...) : StreamSource |
|
|
||||||
| XsltInjection.java:35:66:35:88 | getInputStream(...) : InputStream | XsltInjection.java:35:44:35:89 | new InputStreamReader(...) : InputStreamReader |
|
|
||||||
| XsltInjection.java:40:45:40:70 | param : String | XsltInjection.java:42:61:42:64 | xslt : String |
|
|
||||||
| XsltInjection.java:42:27:42:66 | new StreamSource(...) : StreamSource | XsltInjection.java:43:5:43:59 | newTransformer(...) |
|
|
||||||
| XsltInjection.java:42:44:42:65 | new StringReader(...) : StringReader | XsltInjection.java:42:27:42:66 | new StreamSource(...) : StreamSource |
|
|
||||||
| XsltInjection.java:42:61:42:64 | xslt : String | XsltInjection.java:42:44:42:65 | new StringReader(...) : StringReader |
|
|
||||||
| XsltInjection.java:47:24:47:78 | new SAXSource(...) : SAXSource | XsltInjection.java:48:5:48:74 | newTransformer(...) |
|
|
||||||
| XsltInjection.java:47:38:47:77 | new InputSource(...) : InputSource | XsltInjection.java:47:24:47:78 | new SAXSource(...) : SAXSource |
|
|
||||||
| XsltInjection.java:47:54:47:76 | getInputStream(...) : InputStream | XsltInjection.java:47:38:47:77 | new InputSource(...) : InputSource |
|
|
||||||
| XsltInjection.java:52:24:52:107 | new SAXSource(...) : SAXSource | XsltInjection.java:53:5:53:59 | newTransformer(...) |
|
|
||||||
| XsltInjection.java:52:44:52:106 | new InputSource(...) : InputSource | XsltInjection.java:52:24:52:107 | new SAXSource(...) : SAXSource |
|
|
||||||
| XsltInjection.java:52:60:52:105 | new InputStreamReader(...) : InputStreamReader | XsltInjection.java:52:44:52:106 | new InputSource(...) : InputSource |
|
|
||||||
| XsltInjection.java:52:82:52:104 | getInputStream(...) : InputStream | XsltInjection.java:52:60:52:105 | new InputStreamReader(...) : InputStreamReader |
|
|
||||||
| XsltInjection.java:57:91:57:113 | getInputStream(...) : InputStream | XsltInjection.java:58:5:58:59 | newTransformer(...) |
|
|
||||||
| XsltInjection.java:62:98:62:143 | new InputStreamReader(...) : InputStreamReader | XsltInjection.java:63:5:63:74 | newTransformer(...) |
|
|
||||||
| XsltInjection.java:62:120:62:142 | getInputStream(...) : InputStream | XsltInjection.java:62:98:62:143 | new InputStreamReader(...) : InputStreamReader |
|
|
||||||
| XsltInjection.java:67:102:67:124 | getInputStream(...) : InputStream | XsltInjection.java:68:5:68:59 | newTransformer(...) |
|
|
||||||
| XsltInjection.java:72:27:72:67 | new StreamSource(...) : StreamSource | XsltInjection.java:76:5:76:34 | newTransformer(...) |
|
|
||||||
| XsltInjection.java:72:44:72:66 | getInputStream(...) : InputStream | XsltInjection.java:72:27:72:67 | new StreamSource(...) : StreamSource |
|
|
||||||
| XsltInjection.java:80:27:80:67 | new StreamSource(...) : StreamSource | XsltInjection.java:83:5:83:34 | newTransformer(...) |
|
|
||||||
| XsltInjection.java:80:44:80:66 | getInputStream(...) : InputStream | XsltInjection.java:80:27:80:67 | new StreamSource(...) : StreamSource |
|
|
||||||
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:90:5:90:35 | load(...) |
|
|
||||||
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:91:5:91:37 | load30(...) |
|
|
||||||
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:92:5:92:37 | load30(...) |
|
|
||||||
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:93:5:93:37 | load30(...) |
|
|
||||||
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:94:5:94:37 | load30(...) |
|
|
||||||
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:95:5:95:37 | load30(...) |
|
|
||||||
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:96:5:96:37 | load30(...) |
|
|
||||||
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:97:5:97:37 | load30(...) |
|
|
||||||
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:98:5:98:37 | load30(...) |
|
|
||||||
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:99:5:99:37 | load30(...) |
|
|
||||||
| XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource |
|
|
||||||
| XsltInjection.java:103:36:103:61 | param : String | XsltInjection.java:104:23:104:27 | param : String |
|
|
||||||
| XsltInjection.java:104:15:104:28 | new URI(...) : URI | XsltInjection.java:108:5:108:46 | load(...) |
|
|
||||||
| XsltInjection.java:104:15:104:28 | new URI(...) : URI | XsltInjection.java:110:5:110:50 | load(...) |
|
|
||||||
| XsltInjection.java:104:23:104:27 | param : String | XsltInjection.java:104:15:104:28 | new URI(...) : URI |
|
|
||||||
| XsltInjection.java:105:27:105:67 | new StreamSource(...) : StreamSource | XsltInjection.java:109:5:109:49 | load(...) |
|
|
||||||
| XsltInjection.java:105:44:105:66 | getInputStream(...) : InputStream | XsltInjection.java:105:27:105:67 | new StreamSource(...) : StreamSource |
|
|
||||||
nodes
|
|
||||||
| XsltInjection.java:30:27:30:67 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
|
|
||||||
| XsltInjection.java:30:44:30:66 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
|
|
||||||
| XsltInjection.java:31:5:31:59 | newTransformer(...) | semmle.label | newTransformer(...) |
|
|
||||||
| XsltInjection.java:35:27:35:90 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
|
|
||||||
| XsltInjection.java:35:44:35:89 | new InputStreamReader(...) : InputStreamReader | semmle.label | new InputStreamReader(...) : InputStreamReader |
|
|
||||||
| XsltInjection.java:35:66:35:88 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
|
|
||||||
| XsltInjection.java:36:5:36:74 | newTransformer(...) | semmle.label | newTransformer(...) |
|
|
||||||
| XsltInjection.java:40:45:40:70 | param : String | semmle.label | param : String |
|
|
||||||
| XsltInjection.java:42:27:42:66 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
|
|
||||||
| XsltInjection.java:42:44:42:65 | new StringReader(...) : StringReader | semmle.label | new StringReader(...) : StringReader |
|
|
||||||
| XsltInjection.java:42:61:42:64 | xslt : String | semmle.label | xslt : String |
|
|
||||||
| XsltInjection.java:43:5:43:59 | newTransformer(...) | semmle.label | newTransformer(...) |
|
|
||||||
| XsltInjection.java:47:24:47:78 | new SAXSource(...) : SAXSource | semmle.label | new SAXSource(...) : SAXSource |
|
|
||||||
| XsltInjection.java:47:38:47:77 | new InputSource(...) : InputSource | semmle.label | new InputSource(...) : InputSource |
|
|
||||||
| XsltInjection.java:47:54:47:76 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
|
|
||||||
| XsltInjection.java:48:5:48:74 | newTransformer(...) | semmle.label | newTransformer(...) |
|
|
||||||
| XsltInjection.java:52:24:52:107 | new SAXSource(...) : SAXSource | semmle.label | new SAXSource(...) : SAXSource |
|
|
||||||
| XsltInjection.java:52:44:52:106 | new InputSource(...) : InputSource | semmle.label | new InputSource(...) : InputSource |
|
|
||||||
| XsltInjection.java:52:60:52:105 | new InputStreamReader(...) : InputStreamReader | semmle.label | new InputStreamReader(...) : InputStreamReader |
|
|
||||||
| XsltInjection.java:52:82:52:104 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
|
|
||||||
| XsltInjection.java:53:5:53:59 | newTransformer(...) | semmle.label | newTransformer(...) |
|
|
||||||
| XsltInjection.java:57:91:57:113 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
|
|
||||||
| XsltInjection.java:58:5:58:59 | newTransformer(...) | semmle.label | newTransformer(...) |
|
|
||||||
| XsltInjection.java:62:98:62:143 | new InputStreamReader(...) : InputStreamReader | semmle.label | new InputStreamReader(...) : InputStreamReader |
|
|
||||||
| XsltInjection.java:62:120:62:142 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
|
|
||||||
| XsltInjection.java:63:5:63:74 | newTransformer(...) | semmle.label | newTransformer(...) |
|
|
||||||
| XsltInjection.java:67:102:67:124 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
|
|
||||||
| XsltInjection.java:68:5:68:59 | newTransformer(...) | semmle.label | newTransformer(...) |
|
|
||||||
| XsltInjection.java:72:27:72:67 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
|
|
||||||
| XsltInjection.java:72:44:72:66 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
|
|
||||||
| XsltInjection.java:76:5:76:34 | newTransformer(...) | semmle.label | newTransformer(...) |
|
|
||||||
| XsltInjection.java:80:27:80:67 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
|
|
||||||
| XsltInjection.java:80:44:80:66 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
|
|
||||||
| XsltInjection.java:83:5:83:34 | newTransformer(...) | semmle.label | newTransformer(...) |
|
|
||||||
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
|
|
||||||
| XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
|
|
||||||
| XsltInjection.java:90:5:90:35 | load(...) | semmle.label | load(...) |
|
|
||||||
| XsltInjection.java:91:5:91:37 | load30(...) | semmle.label | load30(...) |
|
|
||||||
| XsltInjection.java:92:5:92:37 | load30(...) | semmle.label | load30(...) |
|
|
||||||
| XsltInjection.java:93:5:93:37 | load30(...) | semmle.label | load30(...) |
|
|
||||||
| XsltInjection.java:94:5:94:37 | load30(...) | semmle.label | load30(...) |
|
|
||||||
| XsltInjection.java:95:5:95:37 | load30(...) | semmle.label | load30(...) |
|
|
||||||
| XsltInjection.java:96:5:96:37 | load30(...) | semmle.label | load30(...) |
|
|
||||||
| XsltInjection.java:97:5:97:37 | load30(...) | semmle.label | load30(...) |
|
|
||||||
| XsltInjection.java:98:5:98:37 | load30(...) | semmle.label | load30(...) |
|
|
||||||
| XsltInjection.java:99:5:99:37 | load30(...) | semmle.label | load30(...) |
|
|
||||||
| XsltInjection.java:103:36:103:61 | param : String | semmle.label | param : String |
|
|
||||||
| XsltInjection.java:104:15:104:28 | new URI(...) : URI | semmle.label | new URI(...) : URI |
|
|
||||||
| XsltInjection.java:104:23:104:27 | param : String | semmle.label | param : String |
|
|
||||||
| XsltInjection.java:105:27:105:67 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
|
|
||||||
| XsltInjection.java:105:44:105:66 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
|
|
||||||
| XsltInjection.java:108:5:108:46 | load(...) | semmle.label | load(...) |
|
|
||||||
| XsltInjection.java:109:5:109:49 | load(...) | semmle.label | load(...) |
|
|
||||||
| XsltInjection.java:110:5:110:50 | load(...) | semmle.label | load(...) |
|
|
||||||
subpaths
|
|
||||||
#select
|
|
||||||
| XsltInjection.java:31:5:31:59 | newTransformer(...) | XsltInjection.java:30:44:30:66 | getInputStream(...) : InputStream | XsltInjection.java:31:5:31:59 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:30:44:30:66 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:36:5:36:74 | newTransformer(...) | XsltInjection.java:35:66:35:88 | getInputStream(...) : InputStream | XsltInjection.java:36:5:36:74 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:35:66:35:88 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:43:5:43:59 | newTransformer(...) | XsltInjection.java:40:45:40:70 | param : String | XsltInjection.java:43:5:43:59 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:40:45:40:70 | param | this user input |
|
|
||||||
| XsltInjection.java:48:5:48:74 | newTransformer(...) | XsltInjection.java:47:54:47:76 | getInputStream(...) : InputStream | XsltInjection.java:48:5:48:74 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:47:54:47:76 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:53:5:53:59 | newTransformer(...) | XsltInjection.java:52:82:52:104 | getInputStream(...) : InputStream | XsltInjection.java:53:5:53:59 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:52:82:52:104 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:58:5:58:59 | newTransformer(...) | XsltInjection.java:57:91:57:113 | getInputStream(...) : InputStream | XsltInjection.java:58:5:58:59 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:57:91:57:113 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:63:5:63:74 | newTransformer(...) | XsltInjection.java:62:120:62:142 | getInputStream(...) : InputStream | XsltInjection.java:63:5:63:74 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:62:120:62:142 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:68:5:68:59 | newTransformer(...) | XsltInjection.java:67:102:67:124 | getInputStream(...) : InputStream | XsltInjection.java:68:5:68:59 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:67:102:67:124 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:76:5:76:34 | newTransformer(...) | XsltInjection.java:72:44:72:66 | getInputStream(...) : InputStream | XsltInjection.java:76:5:76:34 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:72:44:72:66 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:83:5:83:34 | newTransformer(...) | XsltInjection.java:80:44:80:66 | getInputStream(...) : InputStream | XsltInjection.java:83:5:83:34 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:80:44:80:66 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:90:5:90:35 | load(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:90:5:90:35 | load(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:91:5:91:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:91:5:91:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:92:5:92:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:92:5:92:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:93:5:93:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:93:5:93:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:94:5:94:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:94:5:94:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:95:5:95:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:95:5:95:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:96:5:96:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:96:5:96:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:97:5:97:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:97:5:97:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:98:5:98:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:98:5:98:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:99:5:99:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:99:5:99:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:108:5:108:46 | load(...) | XsltInjection.java:103:36:103:61 | param : String | XsltInjection.java:108:5:108:46 | load(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:103:36:103:61 | param | this user input |
|
|
||||||
| XsltInjection.java:109:5:109:49 | load(...) | XsltInjection.java:105:44:105:66 | getInputStream(...) : InputStream | XsltInjection.java:109:5:109:49 | load(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:105:44:105:66 | getInputStream(...) | this user input |
|
|
||||||
| XsltInjection.java:110:5:110:50 | load(...) | XsltInjection.java:103:36:103:61 | param : String | XsltInjection.java:110:5:110:50 | load(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:103:36:103:61 | param | this user input |
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
experimental/Security/CWE/CWE-074/XsltInjection.ql
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/Saxon-HE-9.9.1-7
|
|
||||||
@@ -25,47 +25,51 @@ import net.sf.saxon.s9api.XdmValue;
|
|||||||
import net.sf.saxon.s9api.XsltCompiler;
|
import net.sf.saxon.s9api.XsltCompiler;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class XsltInjection {
|
public class XsltInjectionTest {
|
||||||
public void testStreamSourceInputStream(Socket socket) throws Exception {
|
public void testStreamSourceInputStream(Socket socket) throws Exception {
|
||||||
StreamSource source = new StreamSource(socket.getInputStream());
|
StreamSource source = new StreamSource(socket.getInputStream());
|
||||||
TransformerFactory.newInstance().newTransformer(source).transform(null, null);
|
TransformerFactory.newInstance().newTransformer(source).transform(null, null); // $hasXsltInjection
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStreamSourceReader(Socket socket) throws Exception {
|
public void testStreamSourceReader(Socket socket) throws Exception {
|
||||||
StreamSource source = new StreamSource(new InputStreamReader(socket.getInputStream()));
|
StreamSource source = new StreamSource(new InputStreamReader(socket.getInputStream()));
|
||||||
TransformerFactory.newInstance().newTemplates(source).newTransformer().transform(null, null);
|
TransformerFactory.newInstance().newTemplates(source).newTransformer().transform(null, null); // $hasXsltInjection
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping
|
@RequestMapping
|
||||||
public void testStreamSourceInjectedParam(@RequestParam String param) throws Exception {
|
public void testStreamSourceInjectedParam(@RequestParam String param) throws Exception {
|
||||||
String xslt = "<xsl:stylesheet [...]" + param + "</xsl:stylesheet>";
|
String xslt = "<xsl:stylesheet [...]" + param + "</xsl:stylesheet>";
|
||||||
StreamSource source = new StreamSource(new StringReader(xslt));
|
StreamSource source = new StreamSource(new StringReader(xslt));
|
||||||
TransformerFactory.newInstance().newTransformer(source).transform(null, null);
|
TransformerFactory.newInstance().newTransformer(source).transform(null, null); // $hasXsltInjection
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSAXSourceInputStream(Socket socket) throws Exception {
|
public void testSAXSourceInputStream(Socket socket) throws Exception {
|
||||||
SAXSource source = new SAXSource(new InputSource(socket.getInputStream()));
|
SAXSource source = new SAXSource(new InputSource(socket.getInputStream()));
|
||||||
TransformerFactory.newInstance().newTemplates(source).newTransformer().transform(null, null);
|
TransformerFactory.newInstance().newTemplates(source).newTransformer().transform(null, null); // $hasXsltInjection
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSAXSourceReader(Socket socket) throws Exception {
|
public void testSAXSourceReader(Socket socket) throws Exception {
|
||||||
SAXSource source = new SAXSource(null, new InputSource(new InputStreamReader(socket.getInputStream())));
|
SAXSource source =
|
||||||
TransformerFactory.newInstance().newTransformer(source).transform(null, null);
|
new SAXSource(null, new InputSource(new InputStreamReader(socket.getInputStream())));
|
||||||
|
TransformerFactory.newInstance().newTransformer(source).transform(null, null); // $hasXsltInjection
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStAXSourceEventReader(Socket socket) throws Exception {
|
public void testStAXSourceEventReader(Socket socket) throws Exception {
|
||||||
StAXSource source = new StAXSource(XMLInputFactory.newInstance().createXMLEventReader(socket.getInputStream()));
|
StAXSource source =
|
||||||
TransformerFactory.newInstance().newTransformer(source).transform(null, null);
|
new StAXSource(XMLInputFactory.newInstance().createXMLEventReader(socket.getInputStream()));
|
||||||
|
TransformerFactory.newInstance().newTransformer(source).transform(null, null); // $hasXsltInjection
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStAXSourceEventStream(Socket socket) throws Exception {
|
public void testStAXSourceEventStream(Socket socket) throws Exception {
|
||||||
StAXSource source = new StAXSource(XMLInputFactory.newInstance().createXMLStreamReader(null, new InputStreamReader(socket.getInputStream())));
|
StAXSource source = new StAXSource(XMLInputFactory.newInstance().createXMLStreamReader(null,
|
||||||
TransformerFactory.newInstance().newTemplates(source).newTransformer().transform(null, null);
|
new InputStreamReader(socket.getInputStream())));
|
||||||
|
TransformerFactory.newInstance().newTemplates(source).newTransformer().transform(null, null); // $hasXsltInjection
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDOMSource(Socket socket) throws Exception {
|
public void testDOMSource(Socket socket) throws Exception {
|
||||||
DOMSource source = new DOMSource(DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(socket.getInputStream()));
|
DOMSource source = new DOMSource(
|
||||||
TransformerFactory.newInstance().newTransformer(source).transform(null, null);
|
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(socket.getInputStream()));
|
||||||
|
TransformerFactory.newInstance().newTransformer(source).transform(null, null); // $hasXsltInjection
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDisabledXXE(Socket socket) throws Exception {
|
public void testDisabledXXE(Socket socket) throws Exception {
|
||||||
@@ -73,30 +77,30 @@ public class XsltInjection {
|
|||||||
TransformerFactory factory = TransformerFactory.newInstance();
|
TransformerFactory factory = TransformerFactory.newInstance();
|
||||||
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
||||||
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
|
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
|
||||||
factory.newTransformer(source).transform(null, null);
|
factory.newTransformer(source).transform(null, null); // $hasXsltInjection
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFeatureSecureProcessingDisabled(Socket socket) throws Exception {
|
public void testFeatureSecureProcessingDisabled(Socket socket) throws Exception {
|
||||||
StreamSource source = new StreamSource(socket.getInputStream());
|
StreamSource source = new StreamSource(socket.getInputStream());
|
||||||
TransformerFactory factory = TransformerFactory.newInstance();
|
TransformerFactory factory = TransformerFactory.newInstance();
|
||||||
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false);
|
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false);
|
||||||
factory.newTransformer(source).transform(null, null);
|
factory.newTransformer(source).transform(null, null); // $hasXsltInjection
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSaxon(Socket socket) throws Exception {
|
public void testSaxon(Socket socket) throws Exception {
|
||||||
StreamSource source = new StreamSource(socket.getInputStream());
|
StreamSource source = new StreamSource(socket.getInputStream());
|
||||||
XsltCompiler compiler = new Processor(true).newXsltCompiler();
|
XsltCompiler compiler = new Processor(true).newXsltCompiler();
|
||||||
|
|
||||||
compiler.compile(source).load().transform();
|
compiler.compile(source).load().transform(); // $hasXsltInjection
|
||||||
compiler.compile(source).load30().transform(null, null);
|
compiler.compile(source).load30().transform(null, null); // $hasXsltInjection
|
||||||
compiler.compile(source).load30().applyTemplates((Source) null);
|
compiler.compile(source).load30().applyTemplates((Source) null); // $hasXsltInjection
|
||||||
compiler.compile(source).load30().applyTemplates((Source) null, null);
|
compiler.compile(source).load30().applyTemplates((Source) null, null); // $hasXsltInjection
|
||||||
compiler.compile(source).load30().applyTemplates((XdmValue) null);
|
compiler.compile(source).load30().applyTemplates((XdmValue) null); // $hasXsltInjection
|
||||||
compiler.compile(source).load30().applyTemplates((XdmValue) null, null);
|
compiler.compile(source).load30().applyTemplates((XdmValue) null, null); // $hasXsltInjection
|
||||||
compiler.compile(source).load30().callFunction(null, null);
|
compiler.compile(source).load30().callFunction(null, null); // $hasXsltInjection
|
||||||
compiler.compile(source).load30().callFunction(null, null, null);
|
compiler.compile(source).load30().callFunction(null, null, null); // $hasXsltInjection
|
||||||
compiler.compile(source).load30().callTemplate(null);
|
compiler.compile(source).load30().callTemplate(null); // $hasXsltInjection
|
||||||
compiler.compile(source).load30().callTemplate(null, null);
|
compiler.compile(source).load30().callTemplate(null, null); // $hasXsltInjection
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping
|
@RequestMapping
|
||||||
@@ -105,23 +109,23 @@ public class XsltInjection {
|
|||||||
StreamSource source = new StreamSource(socket.getInputStream());
|
StreamSource source = new StreamSource(socket.getInputStream());
|
||||||
XsltCompiler compiler = new Processor(true).newXsltCompiler();
|
XsltCompiler compiler = new Processor(true).newXsltCompiler();
|
||||||
|
|
||||||
compiler.loadExecutablePackage(uri).load().transform();
|
compiler.loadExecutablePackage(uri).load().transform(); // $hasXsltInjection
|
||||||
compiler.compilePackage(source).link().load().transform();
|
compiler.compilePackage(source).link().load().transform(); // $hasXsltInjection
|
||||||
compiler.loadLibraryPackage(uri).link().load().transform();
|
compiler.loadLibraryPackage(uri).link().load().transform(); // $hasXsltInjection
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testOkFeatureSecureProcessing(Socket socket) throws Exception {
|
public void testOkFeatureSecureProcessing(Socket socket) throws Exception {
|
||||||
StreamSource source = new StreamSource(socket.getInputStream());
|
StreamSource source = new StreamSource(socket.getInputStream());
|
||||||
TransformerFactory factory = TransformerFactory.newInstance();
|
TransformerFactory factory = TransformerFactory.newInstance();
|
||||||
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
factory.newTransformer(source).transform(null, null);
|
factory.newTransformer(source).transform(null, null); // Safe
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testOkSaxon(Socket socket) throws Exception {
|
public void testOkSaxon(Socket socket) throws Exception {
|
||||||
StreamSource source = new StreamSource(socket.getInputStream());
|
StreamSource source = new StreamSource(socket.getInputStream());
|
||||||
XsltCompiler compiler = new Processor(true).newXsltCompiler();
|
XsltCompiler compiler = new Processor(true).newXsltCompiler();
|
||||||
|
|
||||||
compiler.compile(source).load().close();
|
compiler.compile(source).load().close(); // Safe
|
||||||
compiler.compile((Source) new Object()).load().transform();
|
compiler.compile((Source) new Object()).load().transform(); // Safe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import java
|
||||||
|
import semmle.code.java.dataflow.TaintTracking
|
||||||
|
import semmle.code.java.dataflow.FlowSources
|
||||||
|
import semmle.code.java.security.XsltInjectionQuery
|
||||||
|
import TestUtilities.InlineExpectationsTest
|
||||||
|
|
||||||
|
class HasXsltInjectionTest extends InlineExpectationsTest {
|
||||||
|
HasXsltInjectionTest() { this = "HasXsltInjectionTest" }
|
||||||
|
|
||||||
|
override string getARelevantTag() { result = "hasXsltInjection" }
|
||||||
|
|
||||||
|
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||||
|
tag = "hasXsltInjection" and
|
||||||
|
exists(DataFlow::Node src, DataFlow::Node sink, XsltInjectionFlowConfig conf |
|
||||||
|
conf.hasFlow(src, sink)
|
||||||
|
|
|
||||||
|
sink.getLocation() = location and
|
||||||
|
element = sink.toString() and
|
||||||
|
value = ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/shiro-core-1.5.2:${testdir}/../../../stubs/spring-ldap-2.3.2
|
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/shiro-core-1.5.2:${testdir}/../../../stubs/spring-ldap-2.3.2:${testdir}/../../../stubs/Saxon-HE-9.9.1-7
|
||||||
|
|||||||
Reference in New Issue
Block a user