From 57e27b445f583edccea7149c5175d19366ab07d1 Mon Sep 17 00:00:00 2001 From: JeremAIh Date: Mon, 25 Oct 2021 15:53:38 +0100 Subject: [PATCH 1/2] added models for python-sh --- stubs/third_party_taint/pythonsh_sinks.pysa | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 stubs/third_party_taint/pythonsh_sinks.pysa diff --git a/stubs/third_party_taint/pythonsh_sinks.pysa b/stubs/third_party_taint/pythonsh_sinks.pysa new file mode 100644 index 00000000000..3f574422f07 --- /dev/null +++ b/stubs/third_party_taint/pythonsh_sinks.pysa @@ -0,0 +1,5 @@ +def sh.which(program: TaintSink[RemoteCodeExecution], paths: TaintSink[RemoteCodeExecution]):... +def sh.command.__init__(self, path: TaintSink[RemoteCodeExecution], search_paths: TaintSink[RemoteCodeExecution]):... +def sh.RunningCommand.__init__(self, cmd:TaintSink[RemoteCodeExecution], call_args:TaintSink[RemoteCodeExecution], stdin, stdout, stderr) +def sh.oproc.__init__(self, command:TaintSink[RemoteCodeExecution], parent_log, cmd:TaintSink[RemoteCodeExecution], stdin, stdout, stderr, call_args:TaintSink[RemoteCodeExecution], pipe, process_assign_lock) +def sh.SelfWrapper.__init__(self, self_module: TaintSink[RemoteCodeExecution], baked_arg: TaintSink[RemoteCodeExecution]) \ No newline at end of file From 0ec90d963222c23826eff2f4d6fafd70ed028599 Mon Sep 17 00:00:00 2001 From: JeremAIh Date: Mon, 8 Nov 2021 18:53:45 +0100 Subject: [PATCH 2/2] added potential vulnerability cases for python-sh in deliberately_vulnerable_flask_app --- .../deliberately_vulnerable_flask_app/app.py | 26 ++++++ .../full_result.json | 88 +++++++++++++++++++ stubs/third_party_taint/pythonsh_sinks.pysa | 10 +-- 3 files changed, 119 insertions(+), 5 deletions(-) diff --git a/documentation/deliberately_vulnerable_flask_app/app.py b/documentation/deliberately_vulnerable_flask_app/app.py index 4cf39f4a8f8..1971e1c069c 100644 --- a/documentation/deliberately_vulnerable_flask_app/app.py +++ b/documentation/deliberately_vulnerable_flask_app/app.py @@ -10,6 +10,7 @@ import requests from flask import Flask, render_template from lxml import etree +import sh.sh as sh app = Flask(__name__) @@ -57,3 +58,28 @@ def definite_ssrf(payload: str) -> None: @app.route("/xxe/") def definite_xxe(payload: str) -> None: etree.fromstring(payload) + + +@app.route("/rce/") # picked +def potential_rce_3(payload: str) -> None: + sh.Command(path=payload, search_paths=[payload]) + + +@app.route("/rce/") # picked +def potential_rce_4(payload: str) -> None: + sh.RunningCommand(payload, call_args=[payload]) + + +@app.route("/rce/") # picked +def potential_rce_5(payload: str) -> None: + sh.OProc(command=payload, cmd=[payload]) + + +@app.route("/rce/") # picked +def potential_rce_6(payload: str) -> None: + sh.which(payload, paths=[payload]) + + +@app.route("/rce/") +def potential_rce_7(payload: str) -> None: + sh.ls(payload, payload) \ No newline at end of file diff --git a/documentation/deliberately_vulnerable_flask_app/full_result.json b/documentation/deliberately_vulnerable_flask_app/full_result.json index b76a52f6ce2..b859115e1b0 100644 --- a/documentation/deliberately_vulnerable_flask_app/full_result.json +++ b/documentation/deliberately_vulnerable_flask_app/full_result.json @@ -102,5 +102,93 @@ "path": "app.py", "stop_column": 36, "stop_line": 28 + }, + { + "line": 65, + "column": 20, + "stop_line": 65, + "stop_column": 27, + "path": "app.py", + "code": 6065, + "name": "Commandline arguments injection may result in RCE", + "description": "Commandline arguments injection may result in RCE [6065]: Data from [UserControlled] source(s) may reach [ExecArgSink] sink(s)", + "define": "app.potential_rce_3" + }, + { + "line": 65, + "column": 42, + "stop_line": 65, + "stop_column": 51, + "path": "app.py", + "code": 6065, + "name": "Commandline arguments injection may result in RCE", + "description": "Commandline arguments injection may result in RCE [6065]: Data from [UserControlled] source(s) may reach [ExecArgSink] sink(s)", + "define": "app.potential_rce_3" + }, + { + "line": 70, + "column": 41, + "stop_line": 70, + "stop_column": 50, + "path": "app.py", + "code": 6065, + "name": "Commandline arguments injection may result in RCE", + "description": "Commandline arguments injection may result in RCE [6065]: Data from [UserControlled] source(s) may reach [ExecArgSink] sink(s)", + "define": "app.potential_rce_4" + }, + { + "line": 70, + "column": 22, + "stop_line": 70, + "stop_column": 29, + "path": "app.py", + "code": 6065, + "name": "Commandline arguments injection may result in RCE", + "description": "Commandline arguments injection may result in RCE [6065]: Data from [UserControlled] source(s) may reach [ExecArgSink] sink(s)", + "define": "app.potential_rce_4" + }, + { + "line": 75, + "column": 21, + "stop_line": 75, + "stop_column": 28, + "path": "app.py", + "code": 6065, + "name": "Commandline arguments injection may result in RCE", + "description": "Commandline arguments injection may result in RCE [6065]: Data from [UserControlled] source(s) may reach [ExecArgSink] sink(s)", + "define": "app.potential_rce_5" + }, + { + "line": 75, + "column": 34, + "stop_line": 75, + "stop_column": 43, + "path": "app.py", + "code": 6065, + "name": "Commandline arguments injection may result in RCE", + "description": "Commandline arguments injection may result in RCE [6065]: Data from [UserControlled] source(s) may reach [ExecArgSink] sink(s)", + "define": "app.potential_rce_5" + }, + { + "line": 80, + "column": 13, + "stop_line": 80, + "stop_column": 20, + "path": "app.py", + "code": 6065, + "name": "Commandline arguments injection may result in RCE", + "description": "Commandline arguments injection may result in RCE [6065]: Data from [UserControlled] source(s) may reach [ExecArgSink] sink(s)", + "define": "app.potential_rce_6" + }, + { + "line": 80, + "column": 28, + "stop_line": 80, + "stop_column": 37, + "path": "app.py", + "code": 6065, + "name": "Commandline arguments injection may result in RCE", + "description": "Commandline arguments injection may result in RCE [6065]: Data from [UserControlled] source(s) may reach [ExecArgSink] sink(s)", + "define": "app.potential_rce_6" } ] diff --git a/stubs/third_party_taint/pythonsh_sinks.pysa b/stubs/third_party_taint/pythonsh_sinks.pysa index 3f574422f07..5f9cfe1b137 100644 --- a/stubs/third_party_taint/pythonsh_sinks.pysa +++ b/stubs/third_party_taint/pythonsh_sinks.pysa @@ -1,5 +1,5 @@ -def sh.which(program: TaintSink[RemoteCodeExecution], paths: TaintSink[RemoteCodeExecution]):... -def sh.command.__init__(self, path: TaintSink[RemoteCodeExecution], search_paths: TaintSink[RemoteCodeExecution]):... -def sh.RunningCommand.__init__(self, cmd:TaintSink[RemoteCodeExecution], call_args:TaintSink[RemoteCodeExecution], stdin, stdout, stderr) -def sh.oproc.__init__(self, command:TaintSink[RemoteCodeExecution], parent_log, cmd:TaintSink[RemoteCodeExecution], stdin, stdout, stderr, call_args:TaintSink[RemoteCodeExecution], pipe, process_assign_lock) -def sh.SelfWrapper.__init__(self, self_module: TaintSink[RemoteCodeExecution], baked_arg: TaintSink[RemoteCodeExecution]) \ No newline at end of file +def sh.sh.command.__init__(self, path:TaintSink[ExecArgSink], search_paths:TaintSink[ExecArgSink]):... +def sh.sh.RunningCommand.__init__(self, cmd:TaintSink[ExecArgSink], call_args:TaintSink[ExecArgSink], stdin, stdout, stderr):... +def sh.sh.OProc.__init__(self, command:TaintSink[ExecArgSink], parent_log, cmd:TaintSink[ExecArgSink], stdin, stdout, stderr, call_args:TaintSink[ExecArgSink], pipe, process_assign_lock):... +def sh.sh.which(program:TaintSink[ExecArgSink], paths:TaintSink[ExecArgSink]):... +def sh.sh.SelfWrapper.__init__(self, self_module:TaintSink[ExecArgSink], baked_arg:TaintSink[ExecArgSink]):... \ No newline at end of file