Skip to content

Commit 3622fb8

Browse files
committed
support more variants of the Headers API
1 parent 3c80200 commit 3622fb8

3 files changed

Lines changed: 74 additions & 18 deletions

File tree

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,14 +1151,19 @@ module NodeJSLib {
11511151
/** An expression that is passed as `http.request({ auth: <expr> }, ...)`. */
11521152
class FetchAuthorization extends CredentialsExpr {
11531153
FetchAuthorization() {
1154-
this =
1155-
moduleImport()
1156-
.getAConstructorInvocation("Headers")
1157-
.getArgument(0)
1158-
.getALocalSource()
1159-
.getAPropertyWrite("Authorization")
1160-
.getRhs()
1161-
.asExpr()
1154+
exists(DataFlow::Node headers |
1155+
headers = moduleImport().getAConstructorInvocation("Headers").getArgument(0)
1156+
or
1157+
headers = moduleImport().getACall().getOptionArgument(1, "headers")
1158+
|
1159+
this = headers.getALocalSource().getAPropertyWrite("Authorization").getRhs().asExpr()
1160+
)
1161+
or
1162+
exists(DataFlow::MethodCallNode appendCall |
1163+
appendCall = moduleImport().getAConstructorInvocation("Headers").getAMethodCall(["append", "set"]) and
1164+
appendCall.getArgument(0).mayHaveStringValue("Authorization") and
1165+
this = appendCall.getArgument(1).asExpr()
1166+
)
11621167
}
11631168

11641169
override string getCredentialsKind() { result = "authorization headers" }

javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,18 @@ nodes
173173
| HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` |
174174
| HardcodedCredentials.js:173:35:173:38 | USER |
175175
| HardcodedCredentials.js:173:43:173:46 | PASS |
176-
| HardcodedCredentials.js:178:28:178:42 | `Basic ${AUTH}` |
177-
| HardcodedCredentials.js:178:28:178:42 | `Basic ${AUTH}` |
178-
| HardcodedCredentials.js:178:37:178:40 | AUTH |
176+
| HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` |
177+
| HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` |
178+
| HardcodedCredentials.js:178:39:178:42 | AUTH |
179+
| HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` |
180+
| HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` |
181+
| HardcodedCredentials.js:188:39:188:42 | AUTH |
182+
| HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` |
183+
| HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` |
184+
| HardcodedCredentials.js:195:46:195:49 | AUTH |
185+
| HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` |
186+
| HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` |
187+
| HardcodedCredentials.js:204:44:204:47 | AUTH |
179188
edges
180189
| HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' |
181190
| HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' |
@@ -240,13 +249,22 @@ edges
240249
| HardcodedCredentials.js:172:11:172:25 | PASS | HardcodedCredentials.js:173:43:173:46 | PASS |
241250
| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:172:11:172:25 | PASS |
242251
| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:172:11:172:25 | PASS |
243-
| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:178:37:178:40 | AUTH |
252+
| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:178:39:178:42 | AUTH |
253+
| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:188:39:188:42 | AUTH |
254+
| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:195:46:195:49 | AUTH |
255+
| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:204:44:204:47 | AUTH |
244256
| HardcodedCredentials.js:173:18:173:49 | base64. ... PASS}`) | HardcodedCredentials.js:173:11:173:49 | AUTH |
245257
| HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | HardcodedCredentials.js:173:18:173:49 | base64. ... PASS}`) |
246258
| HardcodedCredentials.js:173:35:173:38 | USER | HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` |
247259
| HardcodedCredentials.js:173:43:173:46 | PASS | HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` |
248-
| HardcodedCredentials.js:178:37:178:40 | AUTH | HardcodedCredentials.js:178:28:178:42 | `Basic ${AUTH}` |
249-
| HardcodedCredentials.js:178:37:178:40 | AUTH | HardcodedCredentials.js:178:28:178:42 | `Basic ${AUTH}` |
260+
| HardcodedCredentials.js:178:39:178:42 | AUTH | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` |
261+
| HardcodedCredentials.js:178:39:178:42 | AUTH | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` |
262+
| HardcodedCredentials.js:188:39:188:42 | AUTH | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` |
263+
| HardcodedCredentials.js:188:39:188:42 | AUTH | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` |
264+
| HardcodedCredentials.js:195:46:195:49 | AUTH | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` |
265+
| HardcodedCredentials.js:195:46:195:49 | AUTH | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` |
266+
| HardcodedCredentials.js:204:44:204:47 | AUTH | HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` |
267+
| HardcodedCredentials.js:204:44:204:47 | AUTH | HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` |
250268
#select
251269
| HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | The hard-coded value "dbuser" is used as $@. | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | user name |
252270
| HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | The hard-coded value "abcdefgh" is used as $@. | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | password |
@@ -301,5 +319,11 @@ edges
301319
| HardcodedCredentials.js:135:41:135:50 | "abcdefgh" | HardcodedCredentials.js:135:41:135:50 | "abcdefgh" | HardcodedCredentials.js:135:41:135:50 | "abcdefgh" | The hard-coded value "abcdefgh" is used as $@. | HardcodedCredentials.js:135:41:135:50 | "abcdefgh" | key |
302320
| HardcodedCredentials.js:160:38:160:48 | "change_me" | HardcodedCredentials.js:160:38:160:48 | "change_me" | HardcodedCredentials.js:160:38:160:48 | "change_me" | The hard-coded value "change_me" is used as $@. | HardcodedCredentials.js:160:38:160:48 | "change_me" | key |
303321
| HardcodedCredentials.js:161:41:161:51 | 'change_me' | HardcodedCredentials.js:161:41:161:51 | 'change_me' | HardcodedCredentials.js:161:41:161:51 | 'change_me' | The hard-coded value "change_me" is used as $@. | HardcodedCredentials.js:161:41:161:51 | 'change_me' | key |
304-
| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:178:28:178:42 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:178:28:178:42 | `Basic ${AUTH}` | authorization headers |
305-
| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:178:28:178:42 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:178:28:178:42 | `Basic ${AUTH}` | authorization headers |
322+
| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | authorization headers |
323+
| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | authorization headers |
324+
| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | authorization headers |
325+
| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` | authorization headers |
326+
| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` | authorization headers |
327+
| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` | authorization headers |
328+
| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` | authorization headers |
329+
| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` | authorization headers |

javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,35 @@
175175
const rsp = await fetch(ENDPOINT, {
176176
method: 'get',
177177
headers: new fetch.Headers({
178-
Authorization: `Basic ${AUTH}`,
179-
'Content-Type': 'application/json'
178+
"Authorization": `Basic ${AUTH}`,
179+
"Content-Type": 'application/json'
180180
})
181181
});
182+
183+
fetch(ENDPOINT, {
184+
method: 'post',
185+
body: JSON.stringify(body),
186+
headers: {
187+
"Content-Type": 'application/json',
188+
"Authorization": `Basic ${AUTH}`
189+
},
190+
})
191+
192+
var headers = new fetch.Headers({
193+
"Content-Type": 'application/json'
194+
});
195+
headers.append("Authorization", `Basic ${AUTH}`)
196+
fetch(ENDPOINT, {
197+
method: 'get',
198+
headers: headers
199+
});
200+
201+
var headers2 = new fetch.Headers({
202+
"Content-Type": 'application/json'
203+
});
204+
headers2.set("Authorization", `Basic ${AUTH}`)
205+
fetch(ENDPOINT, {
206+
method: 'get',
207+
headers: headers2
208+
});
182209
});

0 commit comments

Comments
 (0)