Merge pull request #2644 from RasmusWL/python-add-deprecated-keyword

Python: Add deprecated keyword to deprecated functions
This commit is contained in:
Taus
2020-01-23 13:41:15 +01:00
committed by GitHub
30 changed files with 119 additions and 144 deletions

View File

@@ -1,31 +1,30 @@
/**
* @name Use of a broken or weak cryptographic algorithm
* @description Using broken or weak cryptographic algorithms can compromise security.
* @kind problem
* @kind path-problem
* @problem.severity warning
* @precision high
* @id py/weak-cryptographic-algorithm
* @tags security
* external/cwe/cwe-327
*/
import python
import semmle.python.security.Paths
import semmle.python.security.SensitiveData
import semmle.python.security.Crypto
class BrokenCryptoConfiguration extends TaintTracking::Configuration {
BrokenCryptoConfiguration() { this = "Broken crypto configuration" }
override predicate isSource(TaintTracking::Source source) { source instanceof SensitiveDataSource }
override predicate isSink(TaintTracking::Sink sink) {
sink instanceof WeakCryptoSink
override predicate isSource(TaintTracking::Source source) {
source instanceof SensitiveDataSource
}
override predicate isSink(TaintTracking::Sink sink) { sink instanceof WeakCryptoSink }
}
from BrokenCryptoConfiguration config, SensitiveDataSource src, WeakCryptoSink sink
where config.hasFlow(src, sink)
select sink, "Sensitive data from $@ is used in a broken or weak cryptographic algorithm.", src , src.toString()
from BrokenCryptoConfiguration config, TaintedPathSource src, TaintedPathSink sink
where config.hasFlowPath(src, sink)
select sink.getSink(), src, sink, "$@ is used in a broken or weak cryptographic algorithm.",
src.getSource(), "Sensitive data"

View File

@@ -1,7 +1,7 @@
/**
* @name Hard-coded credentials
* @description Credentials are hard coded in the source code of the application.
* @kind problem
* @kind path-problem
* @problem.severity error
* @precision medium
* @id py/hardcoded-credentials
@@ -12,22 +12,20 @@
*/
import python
import semmle.python.security.Paths
import semmle.python.security.TaintTracking
import semmle.python.filters.Tests
class HardcodedValue extends TaintKind {
HardcodedValue() {
this = "hard coded value"
}
HardcodedValue() { this = "hard coded value" }
}
bindingset[char, fraction]
predicate fewer_characters_than(StrConst str, string char, float fraction) {
exists(string text, int chars |
text = str.getText() and
chars = count(int i | text.charAt(i) = char) |
chars = count(int i | text.charAt(i) = char)
|
/* Allow one character */
chars = 1 or
chars < text.length() * fraction
@@ -46,22 +44,15 @@ predicate possible_reflective_name(string name) {
exists(Object::builtin(name))
}
int char_count(StrConst str) {
result = count(string c | c = str.getText().charAt(_))
}
int char_count(StrConst str) { result = count(string c | c = str.getText().charAt(_)) }
predicate capitalized_word(StrConst str) {
str.getText().regexpMatch("[A-Z][a-z]+")
}
predicate capitalized_word(StrConst str) { str.getText().regexpMatch("[A-Z][a-z]+") }
predicate format_string(StrConst str) {
str.getText().matches("%{%}%")
}
predicate format_string(StrConst str) { str.getText().matches("%{%}%") }
predicate maybeCredential(ControlFlowNode f) {
/* A string that is not too short and unlikely to be text or an identifier. */
exists(StrConst str |
str = f.getNode() |
exists(StrConst str | str = f.getNode() |
/* At least 10 characters */
str.getText().length() > 9 and
/* Not too much whitespace */
@@ -69,10 +60,9 @@ predicate maybeCredential(ControlFlowNode f) {
/* or underscores */
fewer_characters_than(str, "_", 0.2) and
/* Not too repetitive */
exists(int chars |
chars = char_count(str) |
exists(int chars | chars = char_count(str) |
chars > 15 or
chars*3 > str.getText().length()*2
chars * 3 > str.getText().length() * 2
) and
not possible_reflective_name(str.getText()) and
not capitalized_word(str) and
@@ -80,9 +70,7 @@ predicate maybeCredential(ControlFlowNode f) {
)
or
/* Or, an integer with over 32 bits */
exists(IntegerLiteral lit |
f.getNode() = lit
|
exists(IntegerLiteral lit | f.getNode() = lit |
not exists(lit.getValue()) and
/* Not a set of flags or round number */
not lit.getN().matches("%00%")
@@ -90,33 +78,22 @@ predicate maybeCredential(ControlFlowNode f) {
}
class HardcodedValueSource extends TaintSource {
HardcodedValueSource() { maybeCredential(this) }
HardcodedValueSource() {
maybeCredential(this)
}
override predicate isSourceOf(TaintKind kind) {
kind instanceof HardcodedValue
}
override predicate isSourceOf(TaintKind kind) { kind instanceof HardcodedValue }
}
class CredentialSink extends TaintSink {
CredentialSink() {
exists(string name |
name.regexpMatch(getACredentialRegex()) and
not name.suffix(name.length()-4) = "file"
|
not name.suffix(name.length() - 4) = "file"
|
any(FunctionObject func).getNamedArgumentForCall(_, name) = this
or
exists(Keyword k |
k.getArg() = name and k.getValue().getAFlowNode() = this
)
exists(Keyword k | k.getArg() = name and k.getValue().getAFlowNode() = this)
or
exists(CompareNode cmp, NameNode n |
n.getId() = name
|
exists(CompareNode cmp, NameNode n | n.getId() = name |
cmp.operands(this, any(Eq eq), n)
or
cmp.operands(n, any(Eq eq), this)
@@ -124,40 +101,31 @@ class CredentialSink extends TaintSink {
)
}
override predicate sinks(TaintKind kind) {
kind instanceof HardcodedValue
}
override predicate sinks(TaintKind kind) { kind instanceof HardcodedValue }
}
/**
* Gets a regular expression for matching names of locations (variables, parameters, keys) that
* indicate the value being held is a credential.
*/
* Gets a regular expression for matching names of locations (variables, parameters, keys) that
* indicate the value being held is a credential.
*/
private string getACredentialRegex() {
result = "(?i).*pass(wd|word|code|phrase)(?!.*question).*" or
result = "(?i).*(puid|username|userid).*" or
result = "(?i).*(cert)(?!.*(format|name)).*"
result = "(?i).*pass(wd|word|code|phrase)(?!.*question).*" or
result = "(?i).*(puid|username|userid).*" or
result = "(?i).*(cert)(?!.*(format|name)).*"
}
class HardcodedCredentialsConfiguration extends TaintTracking::Configuration {
HardcodedCredentialsConfiguration() { this = "Hardcoded coredentials configuration" }
override predicate isSource(TaintTracking::Source source) { source instanceof HardcodedValueSource }
override predicate isSink(TaintTracking::Sink sink) {
sink instanceof CredentialSink
override predicate isSource(TaintTracking::Source source) {
source instanceof HardcodedValueSource
}
override predicate isSink(TaintTracking::Sink sink) { sink instanceof CredentialSink }
}
from HardcodedCredentialsConfiguration config, TaintSource src, TaintSink sink
where config.hasFlow(src, sink) and
not any(TestScope test).contains(src.(ControlFlowNode).getNode())
select sink, "Use of hardcoded credentials from $@.", src, src.toString()
from HardcodedCredentialsConfiguration config, TaintedPathSource src, TaintedPathSink sink
where
config.hasFlowPath(src, sink) and
not any(TestScope test).contains(src.getAstNode())
select sink.getSink(), src, sink, "Use of $@.", src.getSource(), "hardcoded credentials"

View File

@@ -25,7 +25,7 @@ Object aFunctionLocalsObject() {
predicate modification_of_locals(ControlFlowNode f) {
f.(SubscriptNode).getValue().refersTo(aFunctionLocalsObject()) and (f.isStore() or f.isDelete())
f.(SubscriptNode).getObject().refersTo(aFunctionLocalsObject()) and (f.isStore() or f.isDelete())
or
exists(string mname, AttrNode attr |
attr = f.(CallNode).getFunction() and

View File

@@ -65,7 +65,7 @@ predicate same_attribute(Attribute a1, Attribute a2) {
int pyflakes_commented_line(File file) {
exists(Comment c | c.getText().toLowerCase().matches("%pyflakes%") |
c.getLocation().hasLocationInfo(file.getName(), result, _, _, _)
c.getLocation().hasLocationInfo(file.getAbsolutePath(), result, _, _, _)
)
}

View File

@@ -30,7 +30,7 @@ predicate mutates_globals(ModuleValue m) {
|
exists(AttrNode attr | attr.getObject() = globals)
or
exists(SubscriptNode sub | sub.getValue() = globals and sub.isStore())
exists(SubscriptNode sub | sub.getObject() = globals and sub.isStore())
)
or
exists(Value enum_convert, ClassValue enum_class |

View File

@@ -206,8 +206,8 @@ predicate file_sanity(string clsname, string problem, string what) {
exists(File file, Folder folder |
clsname = file.getAQlClass() and
problem = "has same name as a folder" and
what = file.getName() and
what = folder.getName()
what = file.getAbsolutePath() and
what = folder.getAbsolutePath()
) or
exists(Container f |
clsname = f.getAQlClass() and

View File

@@ -21,14 +21,14 @@ predicate sorted_by_location(DuplicateBlock x, DuplicateBlock y) {
if x.sourceFile() = y.sourceFile() then
x.sourceStartLine() < y.sourceStartLine()
else
x.sourceFile().getName() < y.sourceFile().getName()
x.sourceFile().getAbsolutePath() < y.sourceFile().getAbsolutePath()
}
from DuplicateBlock d, DuplicateBlock other
where d.sourceLines() > 10 and
other.getEquivalenceClass() = d.getEquivalenceClass() and
sorted_by_location(other, d)
select
d,
select
d,
"Duplicate code: " + d.sourceLines() + " lines are duplicated at " +
other.sourceFile().getShortName() + ":" + other.sourceStartLine().toString()

View File

@@ -9,17 +9,17 @@ class File extends Container {
}
/** DEPRECATED: Use `getAbsolutePath` instead. */
override string getName() {
files(this, result, _, _, _)
deprecated override string getName() {
result = this.getAbsolutePath()
}
/** DEPRECATED: Use `getAbsolutePath` instead. */
string getFullName() {
result = getName()
deprecated string getFullName() {
result = this.getAbsolutePath()
}
predicate hasLocationInfo(string filepath, int bl, int bc, int el, int ec) {
this.getName() = filepath and bl = 0 and bc = 0 and el = 0 and ec = 0
this.getAbsolutePath() = filepath and bl = 0 and bc = 0 and el = 0 and ec = 0
}
/** Whether this file is a source code file. */
@@ -97,17 +97,17 @@ class Folder extends Container {
}
/** DEPRECATED: Use `getAbsolutePath` instead. */
override string getName() {
folders(this, result, _)
deprecated override string getName() {
result = this.getAbsolutePath()
}
/** DEPRECATED: Use `getBaseName` instead. */
string getSimple() {
deprecated string getSimple() {
folders(this, _, result)
}
predicate hasLocationInfo(string filepath, int bl, int bc, int el, int ec) {
this.getName() = filepath and bl = 0 and bc = 0 and el = 0 and ec = 0
this.getAbsolutePath() = filepath and bl = 0 and bc = 0 and el = 0 and ec = 0
}
override string getAbsolutePath() {
@@ -427,11 +427,11 @@ class Location extends @location {
}
string toString() {
result = this.getPath().getName() + ":" + this.getStartLine().toString()
result = this.getPath().getAbsolutePath() + ":" + this.getStartLine().toString()
}
predicate hasLocationInfo(string filepath, int bl, int bc, int el, int ec) {
exists(File f | f.getName() = filepath |
exists(File f | f.getAbsolutePath() = filepath |
locations_default(this, f, bl, bc, el, ec)
or
exists(Module m | m.getFile() = f |
@@ -445,7 +445,7 @@ class Location extends @location {
class Line extends @py_line {
predicate hasLocationInfo(string filepath, int bl, int bc, int el, int ec) {
exists(Module m | m.getFile().getName() = filepath and
exists(Module m | m.getFile().getAbsolutePath() = filepath and
el = bl and bc = 1 and
py_line_lengths(this, m, bl, ec))
}

View File

@@ -606,7 +606,7 @@ class SubscriptNode extends ControlFlowNode {
/** DEPRECATED: Use `getObject()` instead.
* This will be formally deprecated before the end 2018 and removed in 2019.*/
ControlFlowNode getValue() {
deprecated ControlFlowNode getValue() {
exists(Subscript s | this.getNode() = s and s.getObject() = result.getNode() and
result.getBasicBlock().dominates(this.getBasicBlock()))
}

View File

@@ -123,7 +123,7 @@ module TaintTracking {
/* Old query API */
/* deprecated */
predicate hasFlow(Source src, Sink sink) {
deprecated predicate hasFlow(Source src, Sink sink) {
exists(PathSource psrc, PathSink psink |
this.hasFlowPath(psrc, psink) and
src = psrc.getNode().asCfgNode() and

View File

@@ -132,7 +132,7 @@ abstract class TaintKind extends string {
* This predicate is present for completeness. It is unlikely that any `TaintKind`
* implementation will ever need to override it.
*/
predicate additionalFlowStepVar(EssaVariable fromvar, EssaVariable tovar) { none() }
deprecated predicate additionalFlowStepVar(EssaVariable fromvar, EssaVariable tovar) { none() }
/** Holds if this kind of taint "taints" `expr`.
*/
@@ -143,7 +143,7 @@ abstract class TaintKind extends string {
}
/** DEPRECATED -- Use getType() instead */
ClassObject getClass() {
deprecated ClassObject getClass() {
none()
}
@@ -380,7 +380,7 @@ abstract class Sanitizer extends string {
* Examples include flow from a request to untrusted part of that request or
* from a socket to data from that socket.
*/
abstract class TaintFlow extends string {
deprecated abstract class TaintFlow extends string {
bindingset[this]
TaintFlow() { any() }

View File

@@ -612,7 +612,7 @@ cached module PointsToInternal {
exists(ControlFlowNode sys_modules_flow, ControlFlowNode n, ControlFlowNode mod |
/* Use previous points-to here to avoid slowing down the recursion too much */
exists(SubscriptNode sub |
sub.getValue() = sys_modules_flow and
sub.getObject() = sys_modules_flow and
pointsTo(sys_modules_flow, _, ObjectInternal::sysModules(), _) and
sub.getIndex() = n and
n.getNode().(StrConst).getText() = name and

View File

@@ -381,52 +381,52 @@ class BuiltinFunctionObject extends BuiltinCallable {
}
/** DEPRECATED -- Use `Object::builtin("apply")` instead. */
Object theApplyFunction() {
deprecated Object theApplyFunction() {
result = Object::builtin("apply")
}
/** DEPRECATED -- Use `Object::builtin("hasattr")` instead. */
Object theHasattrFunction() {
deprecated Object theHasattrFunction() {
result = Object::builtin("hasattr")
}
/** DEPRECATED -- Use `Object::builtin("len")` instead. */
Object theLenFunction() {
deprecated Object theLenFunction() {
result = Object::builtin("len")
}
/** DEPRECATED -- Use `Object::builtin("format")` instead. */
Object theFormatFunction() {
deprecated Object theFormatFunction() {
result = Object::builtin("format")
}
/** DEPRECATED -- Use `Object::builtin("open")` instead. */
Object theOpenFunction() {
deprecated Object theOpenFunction() {
result = Object::builtin("open")
}
/** DEPRECATED -- Use `Object::builtin("print")` instead. */
Object thePrintFunction() {
deprecated Object thePrintFunction() {
result = Object::builtin("print")
}
/** DEPRECATED -- Use `Object::builtin("input")` instead. */
Object theInputFunction() {
deprecated Object theInputFunction() {
result = Object::builtin("input")
}
/** DEPRECATED -- Use `Object::builtin("locals")` instead. */
Object theLocalsFunction() {
deprecated Object theLocalsFunction() {
result = Object::builtin("locals")
}
/** DEPRECATED -- Use `Object::builtin("globals")()` instead. */
Object theGlobalsFunction() {
deprecated Object theGlobalsFunction() {
result = Object::builtin("globals")
}
/** DEPRECATED -- Use `Object::builtin("sysExit()` instead. */
Object theExitFunctionObject() {
deprecated Object theExitFunctionObject() {
result = ModuleObject::named("sys").attr("exit")
}

View File

@@ -7,5 +7,5 @@ from ControlFlowNode f, Location l, Context c
where not PointsToInternal::reachableBlock(f.getBasicBlock(), c) and c.isImport() and
(f.getNode() instanceof FunctionExpr or f.getNode() instanceof ClassExpr) and
l = f.getLocation() and l.getFile().getName().matches("%test.py")
select l.getStartLine()
l = f.getLocation() and l.getFile().getShortName() = "test.py"
select l.getStartLine()

View File

@@ -1,13 +1,13 @@
import python
string short_loc(Location l) {
result = l.getFile().getShortName() + ":" + l.getStartLine()
result = l.getFile().getShortName() + ":" + l.getStartLine()
}
from ControlFlowNode use, Object obj, ControlFlowNode orig, int line
where use.refersTo(obj, orig) and
use.getLocation().getFile().getName().matches("%test.py") and
use.getLocation().getFile().getShortName() = "test.py" and
line = use.getLocation().getStartLine() and
not line = 0

View File

@@ -3,5 +3,5 @@ import python
import semmle.python.pointsto.PointsTo
from ControlFlowNode f, Location l
where not PointsToInternal::reachableBlock(f.getBasicBlock(), _) and l = f.getLocation() and l.getFile().getName().matches("%test.py")
select l.getStartLine()
where not PointsToInternal::reachableBlock(f.getBasicBlock(), _) and l = f.getLocation() and l.getFile().getShortName() = "test.py"
select l.getStartLine()

View File

@@ -10,12 +10,12 @@ import python
import external.CodeDuplication
predicate lexically_sorted(DuplicateBlock dup1, DuplicateBlock dup2) {
dup1.sourceFile().getName() < dup2.sourceFile().getName()
dup1.sourceFile().getAbsolutePath() < dup2.sourceFile().getAbsolutePath()
or
dup1.sourceFile().getName() = dup2.sourceFile().getName() and dup1.sourceStartLine() < dup2.sourceStartLine()
dup1.sourceFile().getAbsolutePath() = dup2.sourceFile().getAbsolutePath() and dup1.sourceStartLine() < dup2.sourceStartLine()
}
from DuplicateBlock dup1, DuplicateBlock dup2
where dup1.getEquivalenceClass() = dup2.getEquivalenceClass()
and lexically_sorted(dup1, dup2)
select dup1.toString(), dup2.toString(), dup1.sourceFile().getShortName(), dup1.sourceStartLine(), dup1.sourceEndLine()
select dup1.toString(), dup2.toString(), dup1.sourceFile().getShortName(), dup1.sourceStartLine(), dup1.sourceEndLine()

View File

@@ -10,12 +10,12 @@ import python
import external.CodeDuplication
predicate lexically_sorted(SimilarBlock dup1, SimilarBlock dup2) {
dup1.sourceFile().getName() < dup2.sourceFile().getName()
dup1.sourceFile().getAbsolutePath() < dup2.sourceFile().getAbsolutePath()
or
dup1.sourceFile().getName() = dup2.sourceFile().getName() and dup1.sourceStartLine() < dup2.sourceStartLine()
dup1.sourceFile().getAbsolutePath() = dup2.sourceFile().getAbsolutePath() and dup1.sourceStartLine() < dup2.sourceStartLine()
}
from SimilarBlock dup1, SimilarBlock dup2
where dup1.getEquivalenceClass() = dup2.getEquivalenceClass()
and lexically_sorted(dup1, dup2)
select dup1, dup2, dup1.sourceFile().getShortName(), dup1.sourceStartLine(), dup1.sourceEndLine()
select dup1, dup2, dup1.sourceFile().getShortName(), dup1.sourceStartLine(), dup1.sourceEndLine()

View File

@@ -1,7 +1,7 @@
import python
from string l, NameNode n
where n.getLocation().getFile().getName().matches("%test.py") and
where n.getLocation().getFile().getShortName() = "test.py" and
(
n.isGlobal() and l = "global"
or

View File

@@ -5,4 +5,4 @@ where
encoding = f.getSpecifiedEncoding()
or
not exists(f.getSpecifiedEncoding()) and encoding = "none"
select f.getName(), encoding
select f.getAbsolutePath(), encoding

View File

@@ -33,6 +33,5 @@ class ExternalStringSource extends TaintSource {
}
from TaintedNode n
where n.getLocation().getFile().getName().matches("%test.py")
where n.getLocation().getFile().getShortName() = "test.py"
select "Taint " + n.getTaintKind(), n.getLocation().toString(), n.getAstNode(), n.getContext()

View File

@@ -4,6 +4,5 @@ import Taint
from TaintedNode n
where n.getLocation().getFile().getName().matches("%test.py")
where n.getLocation().getFile().getShortName() = "test.py"
select "Taint " + n.getTaintKind(), n.getLocation().toString(), n.getCfgNode().getNode(), n.getContext()

View File

@@ -4,10 +4,10 @@ import Taint
from TaintedNode n, TaintedNode s
where n.getLocation().getFile().getName().matches("%test.py") and
s.getLocation().getFile().getName().matches("%test.py") and
where n.getLocation().getFile().getShortName() = "test.py" and
s.getLocation().getFile().getShortName() = "test.py" and
s = n.getASuccessor()
select
select
"Taint " + n.getTaintKind(), n.getLocation().toString(), n.getAstNode(), n.getContext(),
" --> ",
"Taint " + s.getTaintKind(), s.getLocation().toString(), s.getAstNode(), s.getContext()

View File

@@ -8,6 +8,5 @@ import semmle.python.security.strings.Untrusted
from TaintedNode node
where node.getLocation().getFile().getName().matches("%falcon/test.py")
where node.getLocation().getFile().getShortName() = "test.py"
select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind()

View File

@@ -8,5 +8,5 @@ import semmle.python.security.strings.Untrusted
from TaintedNode node
where node.getLocation().getFile().getName().matches("%test.py")
where node.getLocation().getFile().getShortName() = "test.py"
select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind()

View File

@@ -7,5 +7,5 @@ import semmle.python.security.strings.Untrusted
from TaintSink sink, TaintKind kind
where sink.sinks(kind) and sink.getLocation().getFile().getName().matches("%test.py")
where sink.sinks(kind) and sink.getLocation().getFile().getShortName() = "test.py"
select sink.getLocation().toString(), sink.(ControlFlowNode).getNode().toString(), kind

View File

@@ -6,7 +6,6 @@ import semmle.python.web.HttpResponse
import semmle.python.security.strings.Untrusted
from TaintedNode node
where node.getLocation().getFile().getName().matches("%test.py")
where node.getLocation().getFile().getShortName() = "test.py"
select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind()

View File

@@ -1,2 +1,8 @@
| test_cryptography.py:8:29:8:37 | Use of weak crypto algorithm | Sensitive data from $@ is used in a broken or weak cryptographic algorithm. | test_cryptography.py:5:17:5:30 | Taint source | Taint source |
| test_pycrypto.py:7:27:7:35 | Use of weak crypto algorithm ARC4 | Sensitive data from $@ is used in a broken or weak cryptographic algorithm. | test_pycrypto.py:5:17:5:30 | Taint source | Taint source |
edges
| test_cryptography.py:5:17:5:30 | a password | test_cryptography.py:8:29:8:37 | a password |
| test_cryptography.py:5:17:5:30 | a password | test_cryptography.py:8:29:8:37 | a password |
| test_pycrypto.py:5:17:5:30 | a password | test_pycrypto.py:7:27:7:35 | a password |
| test_pycrypto.py:5:17:5:30 | a password | test_pycrypto.py:7:27:7:35 | a password |
#select
| test_cryptography.py:8:29:8:37 | dangerous | test_cryptography.py:5:17:5:30 | a password | test_cryptography.py:8:29:8:37 | a password | $@ is used in a broken or weak cryptographic algorithm. | test_cryptography.py:5:17:5:30 | get_password() | Sensitive data |
| test_pycrypto.py:7:27:7:35 | dangerous | test_pycrypto.py:5:17:5:30 | a password | test_pycrypto.py:7:27:7:35 | a password | $@ is used in a broken or weak cryptographic algorithm. | test_pycrypto.py:5:17:5:30 | get_password() | Sensitive data |

View File

@@ -6,5 +6,5 @@ import semmle.python.security.SensitiveData
import semmle.python.security.Crypto
from TaintedNode n, AstNode src
where src = n.getAstNode() and src.getLocation().getFile().getName().matches("%test%")
where src = n.getAstNode() and src.getLocation().getFile().getAbsolutePath().matches("%test%")
select "Taint " + n.getTaintKind(), n.getLocation(), src, n.getContext()

View File

@@ -1,2 +1,8 @@
| test.py:14:18:14:25 | Taint sink | Use of hardcoded credentials from $@. | test.py:5:12:5:24 | Taint source | Taint source |
| test.py:15:18:15:25 | Taint sink | Use of hardcoded credentials from $@. | test.py:6:12:6:25 | Taint source | Taint source |
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 |
#select
| test.py:14:18:14:25 | USERNAME | test.py:5:12:5:24 | hard coded value | test.py:14:18:14:25 | hard coded value | Use of $@. | test.py:5:12:5:24 | Str | hardcoded credentials |
| test.py:15:18:15:25 | PASSWORD | test.py:6:12:6:25 | hard coded value | test.py:15:18:15:25 | hard coded value | Use of $@. | test.py:6:12:6:25 | Str | hardcoded credentials |