Skip to content

Commit c87fe95

Browse files
authored
Merge pull request github#6258 from erik-krogh/case
Approved by asgerf
2 parents b34f444 + d22ebad commit c87fe95

File tree

4 files changed

+95
-0
lines changed

4 files changed

+95
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
lgtm,codescanning
2+
* The dataflow libraries now model dataflow through case changing libraries.
3+
Affected packages are
4+
[change-case](https://www.npmjs.com/package/change-case),
5+
[camel-case](https://www.npmjs.com/package/camel-case),
6+
[pascal-case](https://www.npmjs.com/package/pascal-case),
7+
[snake-case](https://www.npmjs.com/package/snake-case),
8+
[kebab-case](https://www.npmjs.com/package/kebab-case),
9+
[param-case](https://www.npmjs.com/package/param-case),
10+
[path-case](https://www.npmjs.com/package/path-case),
11+
[sentence-case](https://www.npmjs.com/package/sentence-case),
12+
[title-case](https://www.npmjs.com/package/title-case),
13+
[upper-case](https://www.npmjs.com/package/upper-case),
14+
[lower-case](https://www.npmjs.com/package/lower-case),
15+
[no-case](https://www.npmjs.com/package/no-case),
16+
[constant-case](https://www.npmjs.com/package/constant-case),
17+
[dot-case](https://www.npmjs.com/package/dot-case),
18+
[upper-case-first](https://www.npmjs.com/package/upper-case-first),
19+
[lower-case-first](https://www.npmjs.com/package/lower-case-first),
20+
[header-case](https://www.npmjs.com/package/header-case),
21+
[capital-case](https://www.npmjs.com/package/capital-case),
22+
[swap-case](https://www.npmjs.com/package/swap-case),
23+
[sponge-case](https://www.npmjs.com/package/sponge-case),
24+
[titleize](https://www.npmjs.com/package/titleize),
25+
[camelcase](https://www.npmjs.com/package/camelcase),
26+
[decamelize](https://www.npmjs.com/package/decamelize)

javascript/ql/src/semmle/javascript/frameworks/StringFormatters.qll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,39 @@ private class LibraryFormatter extends PrintfStyleCall {
103103

104104
override predicate returnsFormatted() { returns = true }
105105
}
106+
107+
/**
108+
* A taint step through a case changing function.
109+
*/
110+
private class CaseChangingStep extends TaintTracking::SharedTaintStep {
111+
override predicate stringManipulationStep(DataFlow::Node pred, DataFlow::Node succ) {
112+
exists(DataFlow::SourceNode callee, DataFlow::CallNode call |
113+
callee = DataFlow::moduleMember("change-case", _) or
114+
callee = DataFlow::moduleMember("camel-case", "camelCase") or
115+
callee = DataFlow::moduleMember("pascal-case", "pascalCase") or
116+
callee = DataFlow::moduleMember("snake-case", "snakeCase") or
117+
callee = DataFlow::moduleImport("kebab-case") or
118+
callee = DataFlow::moduleMember("kebab-case", "reverse") or
119+
callee = DataFlow::moduleMember("param-case", "paramCase") or
120+
callee = DataFlow::moduleMember("path-case", "pathCase") or
121+
callee = DataFlow::moduleMember("sentence-case", "sentenceCase") or
122+
callee = DataFlow::moduleMember("title-case", "titleCase") or
123+
callee = DataFlow::moduleMember("upper-case", ["upperCase", "localeUpperCase"]) or
124+
callee = DataFlow::moduleMember("lower-case", ["lowerCase", "localeLowerCase"]) or
125+
callee = DataFlow::moduleMember("no-case", "noCase") or
126+
callee = DataFlow::moduleMember("constant-case", "constantCase") or
127+
callee = DataFlow::moduleMember("dot-case", "dotCase") or
128+
callee = DataFlow::moduleMember("upper-case-first", "upperCaseFirst") or
129+
callee = DataFlow::moduleMember("lower-case-first", "lowerCaseFirst") or
130+
callee = DataFlow::moduleMember("header-case", "headerCase") or
131+
callee = DataFlow::moduleMember("capital-case", "capitalCase") or
132+
callee = DataFlow::moduleMember("swap-case", "swapCase") or
133+
callee = DataFlow::moduleMember("sponge-case", "spongeCase") or
134+
callee = DataFlow::moduleImport(["titleize", "camelcase", "decamelize"])
135+
|
136+
call = callee.getACall() and
137+
pred = call.getArgument(0) and
138+
succ = call
139+
)
140+
}
141+
}

javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ typeInferenceMismatch
3535
| callbacks.js:53:23:53:30 | source() | callbacks.js:58:10:58:10 | x |
3636
| capture-flow.js:9:11:9:18 | source() | capture-flow.js:14:10:14:16 | outer() |
3737
| captured-sanitizer.js:25:3:25:10 | source() | captured-sanitizer.js:15:10:15:10 | x |
38+
| case.js:2:16:2:23 | source() | case.js:5:8:5:35 | changeC ... source) |
39+
| case.js:2:16:2:23 | source() | case.js:8:8:8:24 | camelCase(source) |
40+
| case.js:2:16:2:23 | source() | case.js:11:8:11:24 | kebabCase(source) |
41+
| case.js:2:16:2:23 | source() | case.js:12:8:12:32 | kebabCa ... source) |
42+
| case.js:2:16:2:23 | source() | case.js:15:8:15:24 | titleCase(source) |
43+
| case.js:2:16:2:23 | source() | case.js:18:8:18:23 | titleize(source) |
44+
| case.js:2:16:2:23 | source() | case.js:21:8:21:26 | secondCamel(source) |
45+
| case.js:2:16:2:23 | source() | case.js:24:8:24:25 | decamelize(source) |
3846
| closure.js:6:15:6:22 | source() | closure.js:8:8:8:31 | string. ... (taint) |
3947
| closure.js:6:15:6:22 | source() | closure.js:9:8:9:25 | string.trim(taint) |
4048
| closure.js:6:15:6:22 | source() | closure.js:10:8:10:33 | string. ... nt, 50) |
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
function foo() {
2+
let source = source();
3+
4+
const changeCase = require("change-case");
5+
sink(changeCase.camelCase(source)); // NOT OK
6+
7+
import { camelCase } from "camel-case";
8+
sink(camelCase(source)); // NOT OK
9+
10+
var kebabCase = require("kebab-case");
11+
sink(kebabCase(source)); // NOT OK
12+
sink(kebabCase.reverse(source)); // NOT OK
13+
14+
import { titleCase } from "title-case";
15+
sink(titleCase(source)); // NOT OK
16+
17+
import titleize from 'titleize';
18+
sink(titleize(source)); // NOT OK
19+
20+
const secondCamel = require('camelcase');
21+
sink(secondCamel(source)); // NOT OK
22+
23+
const decamelize = require('decamelize');
24+
sink(decamelize(source)); // NOT OK
25+
}

0 commit comments

Comments
 (0)