add jsonpickle and pexpect libs in case of unsafe decoding and secondary command execution, add proper test cases

This commit is contained in:
amammad
2024-02-25 17:15:35 +04:00
committed by Taus
parent 7e93102097
commit 0a765cc94a
13 changed files with 169 additions and 2 deletions

View File

@@ -34,6 +34,7 @@ private import semmle.python.frameworks.Idna
private import semmle.python.frameworks.Invoke
private import semmle.python.frameworks.Jmespath
private import semmle.python.frameworks.Joblib
private import semmle.python.frameworks.JsonPickle
private import semmle.python.frameworks.Ldap
private import semmle.python.frameworks.Ldap3
private import semmle.python.frameworks.Libtaxii
@@ -48,6 +49,7 @@ private import semmle.python.frameworks.Oracledb
private import semmle.python.frameworks.Pandas
private import semmle.python.frameworks.Paramiko
private import semmle.python.frameworks.Peewee
private import semmle.python.frameworks.Pexpect
private import semmle.python.frameworks.Phoenixdb
private import semmle.python.frameworks.Psycopg
private import semmle.python.frameworks.Psycopg2

View File

@@ -0,0 +1,32 @@
/**
* Provides classes modeling security-relevant aspects of the `jsonpickle` PyPI package.
* See https://pypi.org/project/jsonpickle/.
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.dataflow.new.RemoteFlowSources
private import semmle.python.Concepts
private import semmle.python.ApiGraphs
/**
* Provides models for the `jsonpickle` PyPI package.
* See https://pypi.org/project/jsonpickle/.
*/
private module Jsonpickle {
/**
* A Call to `jsonpickle.decode`.
* See https://jsonpickle.readthedocs.io/en/latest/api.html#jsonpickle.decode
*/
private class JsonpickleDecode extends Decoding::Range, API::CallNode {
JsonpickleDecode() { this = API::moduleImport("jsonpickle").getMember("decode").getACall() }
override predicate mayExecuteInput() { any() }
override DataFlow::Node getAnInput() { result = this.getParameter(0, "string").asSink() }
override DataFlow::Node getOutput() { result = this }
override string getFormat() { result = "pickle" }
}
}

View File

@@ -14,7 +14,7 @@ private import semmle.python.ApiGraphs
* See https://pypi.org/project/paramiko/.
*/
private module Paramiko {
/*
/**
* The first argument of `paramiko.ProxyCommand`.
*
* the `paramiko.ProxyCommand` is equivalent of `ssh -o ProxyCommand="CMD"`
@@ -22,7 +22,6 @@ private module Paramiko {
*
* See https://paramiko.pydata.org/docs/reference/api/paramiko.eval.html
*/
class ParamikoProxyCommand extends SystemCommandExecution::Range, API::CallNode {
ParamikoProxyCommand() {
this = API::moduleImport("paramiko").getMember("ProxyCommand").getACall()

View File

@@ -0,0 +1,46 @@
/**
* Provides classes modeling security-relevant aspects of the `pexpect` PyPI package.
* See https://pypi.org/project/pexpect/.
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.dataflow.new.RemoteFlowSources
private import semmle.python.Concepts
private import semmle.python.ApiGraphs
/**
* Provides models for the `pexpect` PyPI package.
* See https://pypi.org/project/pexpect/.
*/
private module Pexpect {
/**
* The calls to `pexpect.*` functions that execute commands
* See https://pexpect.readthedocs.io/en/stable/api/pexpect.html#pexpect.spawn
* See https://pexpect.readthedocs.io/en/stable/api/pexpect.html#pexpect.run
*/
class PexpectCommandExec extends SystemCommandExecution::Range, API::CallNode {
PexpectCommandExec() {
this = API::moduleImport("pexpect").getMember(["run", "runu", "spawn", "spawnu"]).getACall()
}
override DataFlow::Node getCommand() { result = this.getParameter(0, "command").asSink() }
override predicate isShellInterpreted(DataFlow::Node arg) { none() }
}
/**
* A call to `pexpect.popen_spawn.PopenSpawn`
* See https://pexpect.readthedocs.io/en/stable/api/popen_spawn.html#pexpect.popen_spawn.PopenSpawn
*/
class PexpectPopenSpawn extends SystemCommandExecution::Range, API::CallNode {
PexpectPopenSpawn() {
this =
API::moduleImport("pexpect").getMember("popen_spawn").getMember("PopenSpawn").getACall()
}
override DataFlow::Node getCommand() { result = this.getParameter(0, "cmd").asSink() }
override predicate isShellInterpreted(DataFlow::Node arg) { none() }
}
}