Merge pull request #3609 from erik-krogh/CredFN

Approved by asgerf, esbena
This commit is contained in:
semmle-qlci
2020-06-05 10:49:01 +01:00
committed by GitHub
5 changed files with 212 additions and 10 deletions

View File

@@ -260,6 +260,23 @@ module ClientRequest {
}
}
/** An expression that is used as a credential in a request. */
private class AuthorizationHeader extends CredentialsExpr {
AuthorizationHeader() {
exists(DataFlow::PropWrite write | write.getPropertyName().regexpMatch("(?i)authorization") |
this = write.getRhs().asExpr()
)
or
exists(DataFlow::MethodCallNode call | call.getMethodName() = ["append", "set"] |
call.getNumArgument() = 2 and
call.getArgument(0).getStringValue().regexpMatch("(?i)authorization") and
this = call.getArgument(1).asExpr()
)
}
override string getCredentialsKind() { result = "authorization header" }
}
/**
* A model of a URL request made using an implementation of the `fetch` API.
*/
@@ -267,18 +284,14 @@ module ClientRequest {
DataFlow::Node url;
FetchUrlRequest() {
exists(string moduleName, DataFlow::SourceNode callee | this = callee.getACall() |
(
moduleName = "node-fetch" or
moduleName = "cross-fetch" or
moduleName = "isomorphic-fetch"
) and
callee = DataFlow::moduleImport(moduleName) and
exists(DataFlow::SourceNode fetch |
fetch = DataFlow::moduleImport(["node-fetch", "cross-fetch", "isomorphic-fetch"])
or
fetch = DataFlow::globalVarRef("fetch") // https://fetch.spec.whatwg.org/#fetch-api
|
this = fetch.getACall() and
url = getArgument(0)
)
or
this = DataFlow::globalVarRef("fetch").getACall() and
url = getArgument(0)
}
override DataFlow::Node getUrl() { result = url }

View File

@@ -20,5 +20,18 @@ module HardcodedCredentials {
override predicate isSource(DataFlow::Node source) { source instanceof Source }
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
override predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg) {
exists(Base64::Encode encode | src = encode.getInput() and trg = encode.getOutput())
or
trg.(StringOps::ConcatenationRoot).getALeaf() = src and
not exists(src.(StringOps::ConcatenationLeaf).getStringValue()) // to avoid e.g. the ":" in `user + ":" + pass` being flagged as a constant credential.
or
exists(DataFlow::MethodCallNode bufferFrom |
bufferFrom = DataFlow::globalVarRef("Buffer").getAMethodCall("from") and
trg = bufferFrom and
src = bufferFrom.getArgument(0)
)
}
}
}

View File

@@ -162,6 +162,52 @@ nodes
| HardcodedCredentials.js:164:35:164:45 | 'change_me' |
| HardcodedCredentials.js:164:35:164:45 | 'change_me' |
| HardcodedCredentials.js:164:35:164:45 | 'change_me' |
| HardcodedCredentials.js:171:11:171:25 | USER |
| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' |
| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' |
| HardcodedCredentials.js:172:11:172:25 | PASS |
| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' |
| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' |
| HardcodedCredentials.js:173:11:173:49 | AUTH |
| HardcodedCredentials.js:173:18:173:49 | base64. ... PASS}`) |
| HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` |
| HardcodedCredentials.js:173:35:173:38 | USER |
| HardcodedCredentials.js:173:43:173:46 | PASS |
| HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` |
| HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` |
| HardcodedCredentials.js:178:39:178:42 | AUTH |
| HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` |
| HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` |
| HardcodedCredentials.js:188:39:188:42 | AUTH |
| HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` |
| HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` |
| HardcodedCredentials.js:195:46:195:49 | AUTH |
| HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` |
| HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` |
| HardcodedCredentials.js:204:44:204:47 | AUTH |
| HardcodedCredentials.js:214:11:214:25 | USER |
| HardcodedCredentials.js:214:18:214:25 | 'sdsdag' |
| HardcodedCredentials.js:214:18:214:25 | 'sdsdag' |
| HardcodedCredentials.js:215:11:215:25 | PASS |
| HardcodedCredentials.js:215:18:215:25 | 'sdsdag' |
| HardcodedCredentials.js:215:18:215:25 | 'sdsdag' |
| HardcodedCredentials.js:216:11:216:49 | AUTH |
| HardcodedCredentials.js:216:18:216:49 | base64. ... PASS}`) |
| HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` |
| HardcodedCredentials.js:216:35:216:38 | USER |
| HardcodedCredentials.js:216:43:216:46 | PASS |
| HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` |
| HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` |
| HardcodedCredentials.js:221:46:221:49 | AUTH |
| HardcodedCredentials.js:231:11:231:29 | username |
| HardcodedCredentials.js:231:22:231:29 | 'sdsdag' |
| HardcodedCredentials.js:231:22:231:29 | 'sdsdag' |
| HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') |
| HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') |
| HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) |
| HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') |
| HardcodedCredentials.js:237:47:237:54 | username |
| HardcodedCredentials.js:237:47:237:71 | usernam ... assword |
edges
| HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' |
| HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' |
@@ -220,6 +266,49 @@ edges
| HardcodedCredentials.js:160:38:160:48 | "change_me" | HardcodedCredentials.js:160:38:160:48 | "change_me" |
| HardcodedCredentials.js:161:41:161:51 | 'change_me' | HardcodedCredentials.js:161:41:161:51 | 'change_me' |
| HardcodedCredentials.js:164:35:164:45 | 'change_me' | HardcodedCredentials.js:164:35:164:45 | 'change_me' |
| HardcodedCredentials.js:171:11:171:25 | USER | HardcodedCredentials.js:173:35:173:38 | USER |
| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:11:171:25 | USER |
| HardcodedCredentials.js:171:18:171:25 | 'sdsdag' | HardcodedCredentials.js:171:11:171:25 | USER |
| HardcodedCredentials.js:172:11:172:25 | PASS | HardcodedCredentials.js:173:43:173:46 | PASS |
| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:172:11:172:25 | PASS |
| HardcodedCredentials.js:172:18:172:25 | 'sdsdag' | HardcodedCredentials.js:172:11:172:25 | PASS |
| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:178:39:178:42 | AUTH |
| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:188:39:188:42 | AUTH |
| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:195:46:195:49 | AUTH |
| HardcodedCredentials.js:173:11:173:49 | AUTH | HardcodedCredentials.js:204:44:204:47 | AUTH |
| HardcodedCredentials.js:173:18:173:49 | base64. ... PASS}`) | HardcodedCredentials.js:173:11:173:49 | AUTH |
| HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` | HardcodedCredentials.js:173:18:173:49 | base64. ... PASS}`) |
| HardcodedCredentials.js:173:35:173:38 | USER | HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` |
| HardcodedCredentials.js:173:43:173:46 | PASS | HardcodedCredentials.js:173:32:173:48 | `${USER}:${PASS}` |
| HardcodedCredentials.js:178:39:178:42 | AUTH | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` |
| HardcodedCredentials.js:178:39:178:42 | AUTH | HardcodedCredentials.js:178:30:178:44 | `Basic ${AUTH}` |
| HardcodedCredentials.js:188:39:188:42 | AUTH | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` |
| HardcodedCredentials.js:188:39:188:42 | AUTH | HardcodedCredentials.js:188:30:188:44 | `Basic ${AUTH}` |
| HardcodedCredentials.js:195:46:195:49 | AUTH | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` |
| HardcodedCredentials.js:195:46:195:49 | AUTH | HardcodedCredentials.js:195:37:195:51 | `Basic ${AUTH}` |
| HardcodedCredentials.js:204:44:204:47 | AUTH | HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` |
| HardcodedCredentials.js:204:44:204:47 | AUTH | HardcodedCredentials.js:204:35:204:49 | `Basic ${AUTH}` |
| HardcodedCredentials.js:214:11:214:25 | USER | HardcodedCredentials.js:216:35:216:38 | USER |
| HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | HardcodedCredentials.js:214:11:214:25 | USER |
| HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | HardcodedCredentials.js:214:11:214:25 | USER |
| HardcodedCredentials.js:215:11:215:25 | PASS | HardcodedCredentials.js:216:43:216:46 | PASS |
| HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | HardcodedCredentials.js:215:11:215:25 | PASS |
| HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | HardcodedCredentials.js:215:11:215:25 | PASS |
| HardcodedCredentials.js:216:11:216:49 | AUTH | HardcodedCredentials.js:221:46:221:49 | AUTH |
| HardcodedCredentials.js:216:18:216:49 | base64. ... PASS}`) | HardcodedCredentials.js:216:11:216:49 | AUTH |
| HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` | HardcodedCredentials.js:216:18:216:49 | base64. ... PASS}`) |
| HardcodedCredentials.js:216:35:216:38 | USER | HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` |
| HardcodedCredentials.js:216:43:216:46 | PASS | HardcodedCredentials.js:216:32:216:48 | `${USER}:${PASS}` |
| HardcodedCredentials.js:221:46:221:49 | AUTH | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` |
| HardcodedCredentials.js:221:46:221:49 | AUTH | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` |
| HardcodedCredentials.js:231:11:231:29 | username | HardcodedCredentials.js:237:47:237:54 | username |
| HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | HardcodedCredentials.js:231:11:231:29 | username |
| HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | HardcodedCredentials.js:231:11:231:29 | username |
| HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) | HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') |
| HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') |
| HardcodedCredentials.js:237:35:237:91 | Buffer. ... ase64') | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') |
| HardcodedCredentials.js:237:47:237:54 | username | HardcodedCredentials.js:237:47:237:71 | usernam ... assword |
| HardcodedCredentials.js:237:47:237:71 | usernam ... assword | HardcodedCredentials.js:237:35:237:72 | Buffer. ... ssword) |
#select
| 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 |
| 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 |
@@ -274,3 +363,14 @@ edges
| 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 |
| 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 |
| 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 |
| 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 header |
| 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 header |
| 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 header |
| 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 header |
| 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 header |
| 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 header |
| 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 header |
| 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 header |
| HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | HardcodedCredentials.js:214:18:214:25 | 'sdsdag' | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | authorization header |
| HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | HardcodedCredentials.js:215:18:215:25 | 'sdsdag' | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:221:37:221:51 | `Basic ${AUTH}` | authorization header |
| HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | HardcodedCredentials.js:231:22:231:29 | 'sdsdag' | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | The hard-coded value "sdsdag" is used as $@. | HardcodedCredentials.js:237:24:237:91 | 'Basic ... ase64') | authorization header |

View File

@@ -163,3 +163,78 @@
var basicAuth = require('express-basic-auth');
basicAuth({users: { [adminName]: 'change_me' }}); // OK
})();
(async function () {
const base64 = require('base-64');
const fetch = require("node-fetch");
const USER = 'sdsdag';
const PASS = 'sdsdag';
const AUTH = base64.encode(`${USER}:${PASS}`);
const rsp = await fetch(ENDPOINT, {
method: 'get',
headers: new fetch.Headers({
"Authorization": `Basic ${AUTH}`,
"Content-Type": 'application/json'
})
});
fetch(ENDPOINT, {
method: 'post',
body: JSON.stringify(body),
headers: {
"Content-Type": 'application/json',
"Authorization": `Basic ${AUTH}`
},
})
var headers = new fetch.Headers({
"Content-Type": 'application/json'
});
headers.append("Authorization", `Basic ${AUTH}`)
fetch(ENDPOINT, {
method: 'get',
headers: headers
});
var headers2 = new fetch.Headers({
"Content-Type": 'application/json'
});
headers2.set("Authorization", `Basic ${AUTH}`)
fetch(ENDPOINT, {
method: 'get',
headers: headers2
});
});
(function () {
const base64 = require('base-64');
const USER = 'sdsdag';
const PASS = 'sdsdag';
const AUTH = base64.encode(`${USER}:${PASS}`);
// browser API
var headers = new Headers();
headers.append("Content-Type", 'application/json');
headers.append("Authorization", `Basic ${AUTH}`);
fetch(ENDPOINT, {
method: 'get',
headers: headers
});
});
(async function () {
import fetch from 'node-fetch';
const username = 'sdsdag';
const password = config.get('some_actually_secrect_password');
const response = await fetch(ENDPOINT, {
method: 'get',
headers: {
'Content-Type': 'application/json',
Authorization: 'Basic ' + Buffer.from(username + ':' + password).toString('base64'),
},
});
})