forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPasswordInConfigurationFile.ql
More file actions
69 lines (65 loc) · 2.25 KB
/
PasswordInConfigurationFile.ql
File metadata and controls
69 lines (65 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/**
* @name Password in configuration file
* @description Storing unencrypted passwords in configuration files is unsafe.
* @kind problem
* @problem.severity warning
* @precision medium
* @id js/password-in-configuration-file
* @tags security
* external/cwe/cwe-256
* external/cwe/cwe-260
* external/cwe/cwe-313
*/
import javascript
import semmle.javascript.RestrictedLocations
import semmle.javascript.security.SensitiveActions
/**
* Holds if some JSON or YAML file contains a property with name `key`
* and value `val`, where `valElement` is the entity corresponding to the
* value.
*
* Dependencies in `package.json` files are excluded by this predicate.
*/
predicate config(string key, string val, Locatable valElement) {
exists(JSONObject obj | not exists(PackageJSON p | obj = p.getADependenciesObject(_)) |
obj.getPropValue(key) = valElement and
val = valElement.(JSONString).getValue()
)
or
exists(YAMLMapping m, YAMLString keyElement |
m.maps(keyElement, valElement) and
key = keyElement.getValue() and
val = valElement.(YAMLString).getValue()
)
}
/**
* Holds if file `f` should be excluded because it looks like it may be
* an API specification, a dictionary file, or a test or example.
*/
predicate exclude(File f) {
f.getRelativePath().regexpMatch("(?i).*(^|/)(lang(uage)?s?|locales?|tests?|examples?|i18n)/.*")
or
f.getStem().regexpMatch("(?i)translations?")
or
f.getExtension().toLowerCase() = "raml"
}
from string key, string val, Locatable valElement, string pwd
where
config(key, val, valElement) and
val != "" and
// exclude possible templates
not val.regexpMatch(Templating::getDelimiterMatchingRegexp()) and
(
key.toLowerCase() = "password" and
pwd = val and
// exclude interpolations of environment variables
not val.regexpMatch("\\$.*|%.*%") and
not PasswordHeuristics::isDummyPassword(val)
or
key.toLowerCase() != "readme" and
// look for `password=...`, but exclude `password=;`, `password="$(...)"`,
// `password=%s` and `password==`
pwd = val.regexpCapture("(?is).*password\\s*=\\s*(?!;|\"?[$`]|%s|=)(\\S+).*", 1)
) and
not exclude(valElement.getFile())
select valElement.(FirstLineOf), "Hard-coded password '" + pwd + "' in configuration file."