Skip to content

Commit bbd60f5

Browse files
committed
JS: add additional flow steps to js/path-injection
1 parent 7ca7bdf commit bbd60f5

File tree

5 files changed

+1021
-0
lines changed

5 files changed

+1021
-0
lines changed

change-notes/1.24/analysis-javascript.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
| Expression has no effect (`js/useless-expression`) | Fewer false positive results | The query now recognizes block-level flow type annotations and ignores the first statement of a try block. |
4040
| Use of call stack introspection in strict mode (`js/strict-mode-call-stack-introspection`) | Fewer false positive results | The query no longer flags expression statements. |
4141
| Missing CSRF middleware (`js/missing-token-validation`) | Fewer false positive results | The query reports fewer duplicates and only flags handlers that explicitly access cookie data. |
42+
| Uncontrolled data used in path expression (`js/path-injection`) | More results | This query now recognizes additional ways dangerous paths can be constructed. |
4243

4344
## Changes to libraries
4445

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,40 @@ module TaintedPath {
6767
read.getPropertyName() != "length" and
6868
srclabel = dstlabel
6969
)
70+
or
71+
// string method calls of interest
72+
exists(DataFlow::MethodCallNode mcn | srclabel = dstlabel |
73+
exists(string substringMethodName |
74+
substringMethodName = "substr" or
75+
substringMethodName = "substring" or
76+
substringMethodName = "slice"
77+
|
78+
mcn.calls(src, substringMethodName) and
79+
// to avoid very dynamic transformations, require at least one fixed index
80+
exists(mcn.getAnArgument().asExpr().getIntValue()) and
81+
dst = mcn
82+
) or
83+
exists(string argumentlessMethodName |
84+
argumentlessMethodName = "toLocaleLowerCase" or
85+
argumentlessMethodName = "toLocaleUpperCase" or
86+
argumentlessMethodName = "toLowerCase" or
87+
argumentlessMethodName = "toUpperCase" or
88+
argumentlessMethodName = "trim" or
89+
argumentlessMethodName = "trimLeft" or
90+
argumentlessMethodName = "trimRight"
91+
|
92+
mcn.calls(src, argumentlessMethodName) and
93+
dst = mcn
94+
)
95+
or
96+
mcn.calls(src, "split") and
97+
dst = mcn and
98+
not exists (DataFlow::Node splitBy |
99+
splitBy = mcn.getArgument(0)|
100+
splitBy.mayHaveStringValue("/") or
101+
any(DataFlow::RegExpLiteralNode reg | reg.getRoot().getAMatchedString() = "/").flowsTo(splitBy)
102+
)
103+
)
70104
}
71105

72106
/**
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
11
| normalizedPaths.js:208:38:208:63 | // OK - ... anyway | Spurious alert |
2+
| tainted-string-steps.js:13:41:13:72 | // NOT ... flagged | Missing alert |
3+
| tainted-string-steps.js:14:41:14:72 | // NOT ... flagged | Missing alert |
4+
| tainted-string-steps.js:15:50:15:81 | // NOT ... flagged | Missing alert |
5+
| tainted-string-steps.js:25:43:25:74 | // NOT ... flagged | Missing alert |
6+
| tainted-string-steps.js:26:49:26:74 | // OK - ... flagged | Spurious alert |

0 commit comments

Comments
 (0)