Skip to content

Commit ccc171c

Browse files
author
Esben Sparre Andreasen
committed
JS: split RemotePropertyInjection.qll
1 parent 063abb5 commit ccc171c

File tree

2 files changed

+75
-59
lines changed

2 files changed

+75
-59
lines changed

javascript/ql/src/semmle/javascript/security/dataflow/RemotePropertyInjection.qll

Lines changed: 5 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,16 @@
22
* Provides a taint tracking configuration for reasoning about injections in
33
* property names, used either for writing into a property, into a header or
44
* for calling an object's method.
5+
*
6+
* Note, for performance reasons: only import this file if
7+
* `RemotePropertyInjection::Configuration` is needed, otherwise
8+
* `RemotePropertyInjectionCustomizations` should be imported instead.
59
*/
610

711
import javascript
8-
import semmle.javascript.frameworks.Express
9-
import PropertyInjectionShared
1012

1113
module RemotePropertyInjection {
12-
/**
13-
* A data flow source for remote property injection.
14-
*/
15-
abstract class Source extends DataFlow::Node { }
16-
17-
/**
18-
* A data flow sink for remote property injection.
19-
*/
20-
abstract class Sink extends DataFlow::Node {
21-
/**
22-
* Gets a string to identify the different types of sinks.
23-
*/
24-
abstract string getMessage();
25-
}
26-
27-
/**
28-
* A sanitizer for remote property injection.
29-
*/
30-
abstract class Sanitizer extends DataFlow::Node { }
14+
import RemotePropertyInjectionCustomizations::RemotePropertyInjection
3115

3216
/**
3317
* A taint-tracking configuration for reasoning about remote property injection.
@@ -45,42 +29,4 @@ module RemotePropertyInjection {
4529
node = StringConcatenation::getRoot(any(ConstantString str).flow())
4630
}
4731
}
48-
49-
/**
50-
* A source of remote user input, considered as a flow source for remote property
51-
* injection.
52-
*/
53-
class RemoteFlowSourceAsSource extends Source {
54-
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
55-
}
56-
57-
/**
58-
* A sink for property writes with dynamically computed property name.
59-
*/
60-
class PropertyWriteSink extends Sink, DataFlow::ValueNode {
61-
PropertyWriteSink() {
62-
exists(DataFlow::PropWrite pw | astNode = pw.getPropertyNameExpr()) or
63-
exists(DeleteExpr expr | expr.getOperand().(PropAccess).getPropertyNameExpr() = astNode)
64-
}
65-
66-
override string getMessage() { result = " a property name to write to." }
67-
}
68-
69-
/**
70-
* A sink for HTTP header writes with dynamically computed header name.
71-
* This sink avoids double-flagging by ignoring `SetMultipleHeaders` since
72-
* the multiple headers use case consists of an objects containing different
73-
* header names as properties. This case is already handled by
74-
* `PropertyWriteSink`.
75-
*/
76-
class HeaderNameSink extends Sink, DataFlow::ValueNode {
77-
HeaderNameSink() {
78-
exists(HTTP::ExplicitHeaderDefinition hd |
79-
not hd instanceof Express::SetMultipleHeaders and
80-
astNode = hd.getNameExpr()
81-
)
82-
}
83-
84-
override string getMessage() { result = " a header name." }
85-
}
8632
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* Provides default sources, sinks and sanitisers for reasoning about
3+
* injections in property names, used either for writing into a
4+
* property, into a header or for calling an object's method, as well
5+
* as extension points for adding your own.
6+
*/
7+
8+
import javascript
9+
import semmle.javascript.frameworks.Express
10+
import PropertyInjectionShared
11+
12+
module RemotePropertyInjection {
13+
/**
14+
* A data flow source for remote property injection.
15+
*/
16+
abstract class Source extends DataFlow::Node { }
17+
18+
/**
19+
* A data flow sink for remote property injection.
20+
*/
21+
abstract class Sink extends DataFlow::Node {
22+
/**
23+
* Gets a string to identify the different types of sinks.
24+
*/
25+
abstract string getMessage();
26+
}
27+
28+
/**
29+
* A sanitizer for remote property injection.
30+
*/
31+
abstract class Sanitizer extends DataFlow::Node { }
32+
33+
/**
34+
* A source of remote user input, considered as a flow source for remote property
35+
* injection.
36+
*/
37+
class RemoteFlowSourceAsSource extends Source {
38+
RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource }
39+
}
40+
41+
/**
42+
* A sink for property writes with dynamically computed property name.
43+
*/
44+
class PropertyWriteSink extends Sink, DataFlow::ValueNode {
45+
PropertyWriteSink() {
46+
exists(DataFlow::PropWrite pw | astNode = pw.getPropertyNameExpr()) or
47+
exists(DeleteExpr expr | expr.getOperand().(PropAccess).getPropertyNameExpr() = astNode)
48+
}
49+
50+
override string getMessage() { result = " a property name to write to." }
51+
}
52+
53+
/**
54+
* A sink for HTTP header writes with dynamically computed header name.
55+
* This sink avoids double-flagging by ignoring `SetMultipleHeaders` since
56+
* the multiple headers use case consists of an objects containing different
57+
* header names as properties. This case is already handled by
58+
* `PropertyWriteSink`.
59+
*/
60+
class HeaderNameSink extends Sink, DataFlow::ValueNode {
61+
HeaderNameSink() {
62+
exists(HTTP::ExplicitHeaderDefinition hd |
63+
not hd instanceof Express::SetMultipleHeaders and
64+
astNode = hd.getNameExpr()
65+
)
66+
}
67+
68+
override string getMessage() { result = " a header name." }
69+
}
70+
}

0 commit comments

Comments
 (0)