Python: Add test for fabric.api.execute

This commit is contained in:
Rasmus Wriedt Larsen
2020-05-25 17:15:09 +02:00
parent 7716cff3d8
commit e04d1ffcd2
6 changed files with 88 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
class SimpleSource extends TaintSource {
SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "taint source" }
}

View File

@@ -0,0 +1,10 @@
| test.py:8 | fail | unsafe | cmd | <NO TAINT> |
| test.py:8 | fail | unsafe | cmd2 | <NO TAINT> |
| test.py:9 | ok | unsafe | safe_arg | <NO TAINT> |
| test.py:9 | ok | unsafe | safe_optional | <NO TAINT> |
| test.py:16 | fail | unsafe | cmd | <NO TAINT> |
| test.py:16 | fail | unsafe | cmd2 | <NO TAINT> |
| test.py:17 | ok | unsafe | safe_arg | <NO TAINT> |
| test.py:17 | ok | unsafe | safe_optional | <NO TAINT> |
| test.py:23 | ok | some_http_handler | cmd | externally controlled string |
| test.py:23 | ok | some_http_handler | cmd2 | externally controlled string |

View File

@@ -0,0 +1,34 @@
import python
import semmle.python.security.TaintTracking
import semmle.python.web.HttpRequest
import semmle.python.security.strings.Untrusted
import Taint
from
Call call, Expr arg, boolean expected_taint, boolean has_taint, string test_res,
string taint_string
where
call.getLocation().getFile().getShortName() = "test.py" and
(
call.getFunc().(Name).getId() = "ensure_tainted" and
expected_taint = true
or
call.getFunc().(Name).getId() = "ensure_not_tainted" and
expected_taint = false
) and
arg = call.getAnArg() and
(
not exists(TaintedNode tainted | tainted.getAstNode() = arg) and
taint_string = "<NO TAINT>" and
has_taint = false
or
exists(TaintedNode tainted | tainted.getAstNode() = arg |
taint_string = tainted.getTaintKind().toString()
) and
has_taint = true
) and
if expected_taint = has_taint then test_res = "ok " else test_res = "fail"
// if expected_taint = has_taint then test_res = "✓" else test_res = "✕"
select arg.getLocation().toString(), test_res, call.getScope().(Function).getName(), arg.toString(),
taint_string

View File

@@ -0,0 +1 @@
semmle-extractor-options: --max-import-depth=2 -p ../../../query-tests/Security/lib/

View File

@@ -0,0 +1,28 @@
"""Test that shows fabric.api.execute propagates taint"""
from fabric.api import run, execute
def unsafe(cmd, safe_arg, cmd2=None, safe_optional=5):
run('./venv/bin/activate && {}'.format(cmd))
ensure_tainted(cmd, cmd2)
ensure_not_tainted(safe_arg, safe_optional)
class Foo(object):
def unsafe(self, cmd, safe_arg, cmd2=None, safe_optional=5):
run('./venv/bin/activate && {}'.format(cmd))
ensure_tainted(cmd, cmd2)
ensure_not_tainted(safe_arg, safe_optional)
def some_http_handler():
cmd = TAINTED_STRING
cmd2 = TAINTED_STRING
ensure_tainted(cmd, cmd2)
execute(unsafe, cmd=cmd, safe_arg='safe_arg', cmd2=cmd2)
foo = Foo()
execute(foo.unsafe, cmd, 'safe_arg', cmd2)

View File

@@ -23,3 +23,7 @@ def sudo(command, shell=True, pty=True, combine_stderr=None, user=None,
quiet=False, warn_only=False, stdout=None, stderr=None, group=None,
timeout=None, shell_escape=None, capture_buffer_size=None):
pass
# https://github.com/fabric/fabric/blob/1.14/fabric/tasks.py#L281
def execute(task, *args, **kwargs):
pass