JS: whitelist some hardcoded dummy-passwords in two queries

This commit is contained in:
Esben Sparre Andreasen
2019-09-03 14:45:15 +02:00
parent aa3f4a7048
commit 0e2d2f8662
7 changed files with 65 additions and 5 deletions

View File

@@ -13,6 +13,7 @@
import javascript
import semmle.javascript.RestrictedLocations
import semmle.javascript.security.SensitiveActions
/**
* Holds if some JSON or YAML file contains a property with name `key`
@@ -56,7 +57,8 @@ where
key.toLowerCase() = "password" and
pwd = val and
// exclude interpolations of environment variables
not val.regexpMatch("\\$.*|%.*%")
not val.regexpMatch("\\$.*|%.*%") and
not PasswordHeuristics::isDummyPassword(val)
or
key.toLowerCase() != "readme" and
// look for `password=...`, but exclude `password=;`, `password="$(...)"`,

View File

@@ -22,8 +22,21 @@ where
// use source value in message if it's available
if source.getNode().asExpr() instanceof ConstantString
then
value = "The hard-coded value \"" + source.getNode().getStringValue() +
"\""
exists(string val, Sink sinkNode |
sinkNode = sink.getNode().(Sink) and
val = source.getNode().getStringValue()
|
(
(
sinkNode.(DefaultCredentialsSink).getKind() = "password" or
sinkNode.(DefaultCredentialsSink).getKind() = "key"
)
implies
// exclude dummy passwords
not PasswordHeuristics::isDummyPassword(val)
) and
value = "The hard-coded value \"" + val + "\""
)
else value = "This hard-coded value"
select source.getNode(), source, sink, value + " is used as $@.", sink.getNode(),
sink.getNode().(Sink).getKind()

View File

@@ -245,3 +245,21 @@ class CleartextPasswordExpr extends SensitiveExpr {
override SensitiveExpr::Classification getClassification() { none() }
}
/**
* Provides heuristics for classifying passwords.
*/
module PasswordHeuristics {
/**
* Holds if `password` looks like a deliberately weak password that the user should change.
*/
bindingset[password]
predicate isDummyPassword(string password) {
password.length() < 4
or
exists(string normalized | normalized = password.toLowerCase() |
count(normalized.charAt(_)) = 1 or
normalized.regexpMatch(".*(pass|test|sample|example|secret|root|admin|user|change|auth).*")
)
}
}

View File

@@ -0,0 +1,9 @@
| | true |
| XXXXXXXX | true |
| abcdefgh | false |
| admin | true |
| change_me | true |
| example_password | true |
| insert-auth-from-gui | true |
| root | true |
| sOKY6ccizpmvF*32so%Q | false |

View File

@@ -0,0 +1,20 @@
import javascript
import semmle.javascript.security.SensitiveActions
string getASamplePassword() {
result = "abcdefgh" or
result = "sOKY6ccizpmvF*32so%Q" or
result = "XXXXXXXX" or
result = "example_password" or
result = "change_me" or
result = "" or
result = "insert-auth-from-gui" or
result = "admin" or
result = "root"
}
from string password, boolean isDummy
where
password = getASamplePassword() and
if PasswordHeuristics::isDummyPassword(password) then isDummy = true else isDummy = false
select password, isDummy

View File

@@ -1,4 +1,3 @@
| mysql-config.json:4:16:4:25 | "abcdefgh" | Hard-coded password 'abcdefgh' in configuration file. |
| tst4.json:2:10:2:38 | "script ... ecret'" | Hard-coded password ''secret'' in configuration file. |
| tst7.yml:2:9:2:6 | \| | Hard-coded password 'abc' in configuration file. |
| tst.yml:7:11:7:19 | change_me | Hard-coded password 'change_me' in configuration file. |

View File

@@ -106,4 +106,3 @@ edges
| HardcodedCredentials.js:130:44:130:53 | 'abcdefgh' | HardcodedCredentials.js:130:44:130:53 | 'abcdefgh' | HardcodedCredentials.js:130:44:130:53 | 'abcdefgh' | The hard-coded value "abcdefgh" is used as $@. | HardcodedCredentials.js:130:44:130:53 | 'abcdefgh' | key |
| HardcodedCredentials.js:131:52:131:61 | 'abcdefgh' | HardcodedCredentials.js:131:52:131:61 | 'abcdefgh' | HardcodedCredentials.js:131:52:131:61 | 'abcdefgh' | The hard-coded value "abcdefgh" is used as $@. | HardcodedCredentials.js:131:52:131:61 | 'abcdefgh' | key |
| 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 |