Python: Model fabric v1.x command injection sinks

This commit is contained in:
Rasmus Wriedt Larsen
2020-03-23 17:49:56 +01:00
parent a57eadaeb6
commit b567205579
5 changed files with 72 additions and 6 deletions

View File

@@ -227,3 +227,31 @@ class FabricGroupRun extends CommandSink {
kind instanceof ExternalStringKind
}
}
// -------------------------------------------------------------------------- //
// Modeling of the 'invoke' package and 'fabric' package (v 1.x)
// -------------------------------------------------------------------------- //
class FabricV1Commands extends CommandSink {
FabricV1Commands() {
// since `run` and `sudo` are decorated, we can't use FunctionValue's :(
exists(CallNode call
|
call = Value::named("fabric.api.local").getACall()
or
call = Value::named("fabric.api.run").getACall()
or
call = Value::named("fabric.api.sudo").getACall()
|
this = call.getArg(0)
or
this = call.getArgByName("command")
)
}
override string toString() { result = "FabricV1Commands" }
override predicate sinks(TaintKind kind) {
kind instanceof ExternalStringKind
}
}

View File

@@ -1,9 +1,12 @@
| fabric_test.py:10:16:10:25 | InvokeContextRun | externally controlled string |
| fabric_test.py:12:15:12:36 | InvokeContextRun | externally controlled string |
| fabric_test.py:16:45:16:54 | FabricGroupRun | externally controlled string |
| fabric_test.py:21:10:21:13 | FabricGroupRun | externally controlled string |
| fabric_test.py:31:14:31:41 | InvokeContextRun | externally controlled string |
| fabric_test.py:33:15:33:64 | InvokeContextRun | externally controlled string |
| fabric_v1_test.py:8:7:8:28 | FabricV1Commands | externally controlled string |
| fabric_v1_test.py:9:5:9:27 | FabricV1Commands | externally controlled string |
| fabric_v1_test.py:10:6:10:38 | FabricV1Commands | externally controlled string |
| fabric_v2_test.py:10:16:10:25 | InvokeContextRun | externally controlled string |
| fabric_v2_test.py:12:15:12:36 | InvokeContextRun | externally controlled string |
| fabric_v2_test.py:16:45:16:54 | FabricGroupRun | externally controlled string |
| fabric_v2_test.py:21:10:21:13 | FabricGroupRun | externally controlled string |
| fabric_v2_test.py:31:14:31:41 | InvokeContextRun | externally controlled string |
| fabric_v2_test.py:33:15:33:64 | InvokeContextRun | externally controlled string |
| invoke_test.py:8:12:8:21 | InvokeRun | externally controlled string |
| invoke_test.py:9:20:9:40 | InvokeRun | externally controlled string |
| invoke_test.py:12:17:12:24 | InvokeRun | externally controlled string |

View File

@@ -0,0 +1,10 @@
"""tests for the 'fabric' package (v1.x)
See http://docs.fabfile.org/en/1.14/tutorial.html
"""
from fabric.api import run, local, sudo
local('echo local execution')
run('echo remote execution')
sudo('echo remote execution with sudo')

View File

@@ -0,0 +1,25 @@
# For the 1.x version
def needs_host(func):
@wraps(func)
def inner(*args, **kwargs):
return func(*args, **kwargs)
return inner
def local(command, capture=False, shell=None):
pass
@needs_host
def run(command, shell=True, pty=True, combine_stderr=None, quiet=False,
warn_only=False, stdout=None, stderr=None, timeout=None, shell_escape=None,
capture_buffer_size=None):
pass
@needs_host
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