Skip to content

Commit 3a436d1

Browse files
committed
do a quick-and-dirty conversion of py/hardcoded-credentials to the new dataflow library
1 parent ae8bf5e commit 3a436d1

File tree

2 files changed

+29
-30
lines changed

2 files changed

+29
-30
lines changed

python/ql/src/Security/CWE-798/HardcodedCredentials.ql

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,10 @@
1313
*/
1414

1515
import python
16-
import semmle.python.security.Paths
17-
import semmle.python.dataflow.TaintTracking
16+
import semmle.python.dataflow.new.DataFlow
17+
import semmle.python.dataflow.new.TaintTracking
1818
import semmle.python.filters.Tests
19-
20-
class HardcodedValue extends TaintKind {
21-
HardcodedValue() { this = "hard coded value" }
22-
}
19+
import DataFlow::PathGraph
2320

2421
bindingset[char, fraction]
2522
predicate fewer_characters_than(StrConst str, string char, float fraction) {
@@ -78,31 +75,27 @@ predicate maybeCredential(ControlFlowNode f) {
7875
)
7976
}
8077

81-
class HardcodedValueSource extends TaintSource {
82-
HardcodedValueSource() { maybeCredential(this) }
83-
84-
override predicate isSourceOf(TaintKind kind) { kind instanceof HardcodedValue }
78+
class HardcodedValueSource extends DataFlow::Node {
79+
HardcodedValueSource() { maybeCredential(this.asCfgNode()) }
8580
}
8681

87-
class CredentialSink extends TaintSink {
82+
class CredentialSink extends DataFlow::Node {
8883
CredentialSink() {
8984
exists(string name |
9085
name.regexpMatch(getACredentialRegex()) and
9186
not name.matches("%file")
9287
|
93-
any(FunctionValue func).getNamedArgumentForCall(_, name) = this
88+
any(FunctionValue func).getNamedArgumentForCall(_, name) = this.asCfgNode()
9489
or
95-
exists(Keyword k | k.getArg() = name and k.getValue().getAFlowNode() = this)
90+
exists(Keyword k | k.getArg() = name and k.getValue().getAFlowNode() = this.asCfgNode())
9691
or
9792
exists(CompareNode cmp, NameNode n | n.getId() = name |
98-
cmp.operands(this, any(Eq eq), n)
93+
cmp.operands(this.asCfgNode(), any(Eq eq), n)
9994
or
100-
cmp.operands(n, any(Eq eq), this)
95+
cmp.operands(n, any(Eq eq), this.asCfgNode())
10196
)
10297
)
10398
}
104-
105-
override predicate sinks(TaintKind kind) { kind instanceof HardcodedValue }
10699
}
107100

108101
/**
@@ -118,16 +111,14 @@ private string getACredentialRegex() {
118111
class HardcodedCredentialsConfiguration extends TaintTracking::Configuration {
119112
HardcodedCredentialsConfiguration() { this = "Hardcoded credentials configuration" }
120113

121-
override predicate isSource(TaintTracking::Source source) {
122-
source instanceof HardcodedValueSource
123-
}
114+
override predicate isSource(DataFlow::Node source) { source instanceof HardcodedValueSource }
124115

125-
override predicate isSink(TaintTracking::Sink sink) { sink instanceof CredentialSink }
116+
override predicate isSink(DataFlow::Node sink) { sink instanceof CredentialSink }
126117
}
127118

128-
from HardcodedCredentialsConfiguration config, TaintedPathSource src, TaintedPathSink sink
119+
from HardcodedCredentialsConfiguration config, DataFlow::PathNode src, DataFlow::PathNode sink
129120
where
130121
config.hasFlowPath(src, sink) and
131-
not any(TestScope test).contains(src.getAstNode())
132-
select src.getSource(), src, sink, "This hardcoded value is $@.", sink.getNode(),
122+
not any(TestScope test).contains(src.getNode().asCfgNode().getNode())
123+
select src.getNode(), src, sink, "This hardcoded value is $@.", sink.getNode(),
133124
"used as credentials"
Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
edges
2-
| test.py:5:12:5:24 | hard coded value | test.py:14:18:14:25 | hard coded value |
3-
| test.py:5:12:5:24 | hard coded value | test.py:14:18:14:25 | hard coded value |
4-
| test.py:6:12:6:25 | hard coded value | test.py:15:18:15:25 | hard coded value |
5-
| test.py:6:12:6:25 | hard coded value | test.py:15:18:15:25 | hard coded value |
2+
| test.py:5:1:5:8 | GSSA Variable USERNAME | test.py:14:18:14:25 | ControlFlowNode for USERNAME |
3+
| test.py:5:12:5:24 | ControlFlowNode for Str | test.py:5:1:5:8 | GSSA Variable USERNAME |
4+
| test.py:6:1:6:8 | GSSA Variable PASSWORD | test.py:15:18:15:25 | ControlFlowNode for PASSWORD |
5+
| test.py:6:12:6:25 | ControlFlowNode for Str | test.py:6:1:6:8 | GSSA Variable PASSWORD |
6+
nodes
7+
| test.py:5:1:5:8 | GSSA Variable USERNAME | semmle.label | GSSA Variable USERNAME |
8+
| test.py:5:12:5:24 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
9+
| test.py:6:1:6:8 | GSSA Variable PASSWORD | semmle.label | GSSA Variable PASSWORD |
10+
| test.py:6:12:6:25 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
11+
| test.py:14:18:14:25 | ControlFlowNode for USERNAME | semmle.label | ControlFlowNode for USERNAME |
12+
| test.py:15:18:15:25 | ControlFlowNode for PASSWORD | semmle.label | ControlFlowNode for PASSWORD |
13+
subpaths
614
#select
7-
| test.py:5:12:5:24 | Str | test.py:5:12:5:24 | hard coded value | test.py:14:18:14:25 | hard coded value | This hardcoded value is $@. | test.py:14:18:14:25 | USERNAME | used as credentials |
8-
| test.py:6:12:6:25 | Str | test.py:6:12:6:25 | hard coded value | test.py:15:18:15:25 | hard coded value | This hardcoded value is $@. | test.py:15:18:15:25 | PASSWORD | used as credentials |
15+
| test.py:5:12:5:24 | ControlFlowNode for Str | test.py:5:12:5:24 | ControlFlowNode for Str | test.py:14:18:14:25 | ControlFlowNode for USERNAME | This hardcoded value is $@. | test.py:14:18:14:25 | ControlFlowNode for USERNAME | used as credentials |
16+
| test.py:6:12:6:25 | ControlFlowNode for Str | test.py:6:12:6:25 | ControlFlowNode for Str | test.py:15:18:15:25 | ControlFlowNode for PASSWORD | This hardcoded value is $@. | test.py:15:18:15:25 | ControlFlowNode for PASSWORD | used as credentials |

0 commit comments

Comments
 (0)