do a quick-and-dirty conversion of py/hardcoded-credentials to the new dataflow library

This commit is contained in:
erik-krogh
2023-06-12 11:56:44 +02:00
parent ae8bf5ed3c
commit 3a436d1f84
2 changed files with 29 additions and 30 deletions

View File

@@ -13,13 +13,10 @@
*/
import python
import semmle.python.security.Paths
import semmle.python.dataflow.TaintTracking
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.filters.Tests
class HardcodedValue extends TaintKind {
HardcodedValue() { this = "hard coded value" }
}
import DataFlow::PathGraph
bindingset[char, fraction]
predicate fewer_characters_than(StrConst str, string char, float fraction) {
@@ -78,31 +75,27 @@ predicate maybeCredential(ControlFlowNode f) {
)
}
class HardcodedValueSource extends TaintSource {
HardcodedValueSource() { maybeCredential(this) }
override predicate isSourceOf(TaintKind kind) { kind instanceof HardcodedValue }
class HardcodedValueSource extends DataFlow::Node {
HardcodedValueSource() { maybeCredential(this.asCfgNode()) }
}
class CredentialSink extends TaintSink {
class CredentialSink extends DataFlow::Node {
CredentialSink() {
exists(string name |
name.regexpMatch(getACredentialRegex()) and
not name.matches("%file")
|
any(FunctionValue func).getNamedArgumentForCall(_, name) = this
any(FunctionValue func).getNamedArgumentForCall(_, name) = this.asCfgNode()
or
exists(Keyword k | k.getArg() = name and k.getValue().getAFlowNode() = this)
exists(Keyword k | k.getArg() = name and k.getValue().getAFlowNode() = this.asCfgNode())
or
exists(CompareNode cmp, NameNode n | n.getId() = name |
cmp.operands(this, any(Eq eq), n)
cmp.operands(this.asCfgNode(), any(Eq eq), n)
or
cmp.operands(n, any(Eq eq), this)
cmp.operands(n, any(Eq eq), this.asCfgNode())
)
)
}
override predicate sinks(TaintKind kind) { kind instanceof HardcodedValue }
}
/**
@@ -118,16 +111,14 @@ private string getACredentialRegex() {
class HardcodedCredentialsConfiguration extends TaintTracking::Configuration {
HardcodedCredentialsConfiguration() { this = "Hardcoded credentials configuration" }
override predicate isSource(TaintTracking::Source source) {
source instanceof HardcodedValueSource
}
override predicate isSource(DataFlow::Node source) { source instanceof HardcodedValueSource }
override predicate isSink(TaintTracking::Sink sink) { sink instanceof CredentialSink }
override predicate isSink(DataFlow::Node sink) { sink instanceof CredentialSink }
}
from HardcodedCredentialsConfiguration config, TaintedPathSource src, TaintedPathSink sink
from HardcodedCredentialsConfiguration config, DataFlow::PathNode src, DataFlow::PathNode sink
where
config.hasFlowPath(src, sink) and
not any(TestScope test).contains(src.getAstNode())
select src.getSource(), src, sink, "This hardcoded value is $@.", sink.getNode(),
not any(TestScope test).contains(src.getNode().asCfgNode().getNode())
select src.getNode(), src, sink, "This hardcoded value is $@.", sink.getNode(),
"used as credentials"

View File

@@ -1,8 +1,16 @@
edges
| test.py:5:12:5:24 | hard coded value | test.py:14:18:14:25 | hard coded value |
| test.py:5:12:5:24 | hard coded value | test.py:14:18:14:25 | hard coded value |
| test.py:6:12:6:25 | hard coded value | test.py:15:18:15:25 | hard coded value |
| test.py:6:12:6:25 | hard coded value | test.py:15:18:15:25 | hard coded value |
| test.py:5:1:5:8 | GSSA Variable USERNAME | test.py:14:18:14:25 | ControlFlowNode for USERNAME |
| test.py:5:12:5:24 | ControlFlowNode for Str | test.py:5:1:5:8 | GSSA Variable USERNAME |
| test.py:6:1:6:8 | GSSA Variable PASSWORD | test.py:15:18:15:25 | ControlFlowNode for PASSWORD |
| test.py:6:12:6:25 | ControlFlowNode for Str | test.py:6:1:6:8 | GSSA Variable PASSWORD |
nodes
| test.py:5:1:5:8 | GSSA Variable USERNAME | semmle.label | GSSA Variable USERNAME |
| test.py:5:12:5:24 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
| test.py:6:1:6:8 | GSSA Variable PASSWORD | semmle.label | GSSA Variable PASSWORD |
| test.py:6:12:6:25 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
| test.py:14:18:14:25 | ControlFlowNode for USERNAME | semmle.label | ControlFlowNode for USERNAME |
| test.py:15:18:15:25 | ControlFlowNode for PASSWORD | semmle.label | ControlFlowNode for PASSWORD |
subpaths
#select
| 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 |
| 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 |
| 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 |
| 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 |