Skip to content

Commit 29e69b3

Browse files
author
Esben Sparre Andreasen
committed
JS: split XpathInjection.qll
1 parent 48b655f commit 29e69b3

File tree

2 files changed

+75
-58
lines changed

2 files changed

+75
-58
lines changed
Lines changed: 7 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,17 @@
11
/**
2-
* Provides a taint-tracking configuration for reasoning about untrusted user input used in XPath expression.
2+
* Provides a taint-tracking configuration for reasoning about
3+
* untrusted user input used in XPath expression.
4+
*
5+
* Note, for performance reasons: only import this file if
6+
* `XpathInjection::Configuration` is needed, otherwise
7+
* `XpathInjectionCustomizations` should be imported instead.
38
*/
49

510
import javascript
611
import semmle.javascript.security.dataflow.DOM
712

813
module XpathInjection {
9-
/**
10-
* A data flow source for untrusted user input used in XPath expression.
11-
*/
12-
abstract class Source extends DataFlow::Node { }
13-
14-
/**
15-
* A data flow sink for untrusted user input used in XPath expression.
16-
*/
17-
abstract class Sink extends DataFlow::Node { }
18-
19-
/**
20-
* A sanitizer for untrusted user input used in XPath expression.
21-
*/
22-
abstract class Sanitizer extends DataFlow::Node { }
14+
import XpathInjectionCustomizations::XpathInjection
2315

2416
/**
2517
* A taint-tracking configuration for untrusted user input used in XPath expression.
@@ -36,47 +28,4 @@ module XpathInjection {
3628
node instanceof Sanitizer
3729
}
3830
}
39-
40-
/** A source of remote user input, considered as a flow source for XPath injection. */
41-
class RemoteSource extends Source {
42-
RemoteSource() { this instanceof RemoteFlowSource }
43-
}
44-
45-
/**
46-
* The `expression` argument to `xpath.parse` or `xpath.select` (and similar) from
47-
* the `xpath` or `xpath.js` npm packages, considered as a flow sink for XPath injection.
48-
*/
49-
class XpathParseSelectSink extends Sink {
50-
XpathParseSelectSink() {
51-
// both packages appear to expose the same API
52-
exists(string xpath | xpath = "xpath" or xpath = "xpath.js" |
53-
// `xpath.parse`, `xpath.select` and `xpath.select1` all interpret their first
54-
// argument as an XPath expression
55-
exists(string m | m = "parse" or m = "select" or m = "select1" |
56-
this = DataFlow::moduleMember(xpath, m).getACall().getArgument(0)
57-
)
58-
or
59-
// `xpath.useNamespaces` returns a function that interprets its first argument
60-
// as an XPath expression
61-
this = DataFlow::moduleMember(xpath, "useNamespaces").getACall().getACall().getArgument(0)
62-
)
63-
}
64-
}
65-
66-
/** A part of the document URL, considered as a flow source for XPath injection. */
67-
class DocumentUrlSource extends Source {
68-
DocumentUrlSource() { this = DOM::locationSource() }
69-
}
70-
71-
/**
72-
* The `expression` argument to `document.evaluate` or `document.createExpression`,
73-
* considered as a flow sink for XPath injection.
74-
*/
75-
class DomXpathSink extends Sink {
76-
DomXpathSink() {
77-
exists(string m | m = "evaluate" or m = "createExpression" |
78-
this = DOM::documentRef().getAMethodCall(m).getArgument(0)
79-
)
80-
}
81-
}
8231
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* Provides default sources, sinks and sanitisers for reasoning about
3+
* untrusted user input used in XPath expression, as well as extension
4+
* points for adding your own.
5+
*/
6+
7+
import javascript
8+
import semmle.javascript.security.dataflow.DOM
9+
10+
module XpathInjection {
11+
/**
12+
* A data flow source for untrusted user input used in XPath expression.
13+
*/
14+
abstract class Source extends DataFlow::Node { }
15+
16+
/**
17+
* A data flow sink for untrusted user input used in XPath expression.
18+
*/
19+
abstract class Sink extends DataFlow::Node { }
20+
21+
/**
22+
* A sanitizer for untrusted user input used in XPath expression.
23+
*/
24+
abstract class Sanitizer extends DataFlow::Node { }
25+
26+
/** A source of remote user input, considered as a flow source for XPath injection. */
27+
class RemoteSource extends Source {
28+
RemoteSource() { this instanceof RemoteFlowSource }
29+
}
30+
31+
/**
32+
* The `expression` argument to `xpath.parse` or `xpath.select` (and similar) from
33+
* the `xpath` or `xpath.js` npm packages, considered as a flow sink for XPath injection.
34+
*/
35+
class XpathParseSelectSink extends Sink {
36+
XpathParseSelectSink() {
37+
// both packages appear to expose the same API
38+
exists(string xpath | xpath = "xpath" or xpath = "xpath.js" |
39+
// `xpath.parse`, `xpath.select` and `xpath.select1` all interpret their first
40+
// argument as an XPath expression
41+
exists(string m | m = "parse" or m = "select" or m = "select1" |
42+
this = DataFlow::moduleMember(xpath, m).getACall().getArgument(0)
43+
)
44+
or
45+
// `xpath.useNamespaces` returns a function that interprets its first argument
46+
// as an XPath expression
47+
this = DataFlow::moduleMember(xpath, "useNamespaces").getACall().getACall().getArgument(0)
48+
)
49+
}
50+
}
51+
52+
/** A part of the document URL, considered as a flow source for XPath injection. */
53+
class DocumentUrlSource extends Source {
54+
DocumentUrlSource() { this = DOM::locationSource() }
55+
}
56+
57+
/**
58+
* The `expression` argument to `document.evaluate` or `document.createExpression`,
59+
* considered as a flow sink for XPath injection.
60+
*/
61+
class DomXpathSink extends Sink {
62+
DomXpathSink() {
63+
exists(string m | m = "evaluate" or m = "createExpression" |
64+
this = DOM::documentRef().getAMethodCall(m).getArgument(0)
65+
)
66+
}
67+
}
68+
}

0 commit comments

Comments
 (0)