Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 558d753

Browse files
Merge pull request #81 from python-security/every_vuln_chain
every vuln chain
2 parents cfbe82f + 4447c75 commit 558d753

31 files changed

+1201
-773
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import os
2+
from flask import Flask, request, send_file
3+
4+
app = Flask(__name__)
5+
6+
def outer(outer_arg, other_arg):
7+
outer_ret_val = outer_arg + 'hey' + other_arg
8+
return outer_ret_val
9+
10+
def inner():
11+
return 'boom'
12+
13+
@app.route('/')
14+
def cat_picture():
15+
image_name = request.args.get('image_name')
16+
if not image_name:
17+
image_name = 'foo'
18+
return 404
19+
foo = outer(inner(), image_name) # Nested call after if caused the problem
20+
send_file(image_name)
21+
return 'idk'
22+
23+
24+
if __name__ == '__main__':
25+
app.run(debug=True)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import subprocess
2+
from flask import Flask, render_template, request
3+
4+
5+
app = Flask(__name__)
6+
7+
8+
@app.route('/multi_chain', methods=['POST'])
9+
def multi_chain():
10+
suggestion = request.form['suggestion']
11+
x = fast_eddie(suggestion, 'the')
12+
y = x + 'foo'
13+
z = minnesota_fats(suggestion, 'sting')
14+
ben = graham(y, z)
15+
16+
subprocess.call(ben, shell=True)
17+
18+
return render_template('multi_chain.html')
19+

‎example/vulnerable_code/path_traversal.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def cat_picture():
1616
if not image_name:
1717
image_name = 'foo'
1818
return 404
19-
foo = outer(inner(), image_name) # Nested call after if caused the problem
19+
foo = outer(inner(), image_name) # Nested call after if caused the problem
2020
send_file(foo)
2121
return 'idk'
2222

‎example/vulnerable_code/path_traversal_sanitised_2.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
def cat_picture():
88
image_name = request.args.get('image_name')
99

10-
if not'..' in image_name:
10+
if '..' in image_name:
1111
return 404
1212
return send_file(os.path.join(os.getcwd(), image_name))
1313

‎pyt/__main__.py‎

Lines changed: 60 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@
66
from datetime import date
77
from pprint import pprint
88

9-
from .argument_helpers import valid_date
9+
from .argument_helpers import (
10+
default_blackbox_mapping_file,
11+
default_trigger_word_file,
12+
valid_date,
13+
VulnerabilityFiles,
14+
UImode
15+
)
1016
from .ast_helper import generate_ast
1117
from .draw import draw_cfgs, draw_lattices
1218
from .constraint_table import initialize_constraint_table, print_table
@@ -72,10 +78,22 @@ def parse_args(args):
7278
print_group.add_argument('-vp', '--verbose-print',
7379
help='Verbose printing of -p.', action='store_true')
7480
print_group.add_argument('-trim', '--trim-reassigned-in',
75-
help='Trims the reassigned list to the vulnerability chain.', action='store_true')
81+
help='Trims the reassigned list to the vulnerability chain.',
82+
action='store_true',
83+
default=False)
84+
print_group.add_argument('-i', '--interactive',
85+
help='Will ask you about each vulnerability chain and blackbox nodes.',
86+
action='store_true',
87+
default=False)
7688

7789
parser.add_argument('-t', '--trigger-word-file',
78-
help='Input trigger word file.', type=str)
90+
help='Input trigger word file.',
91+
type=str,
92+
default=default_trigger_word_file)
93+
parser.add_argument('-b', '--blackbox-mapping-file',
94+
help='Input blackbox mapping file.',
95+
type=str,
96+
default=default_blackbox_mapping_file)
7997
parser.add_argument('-py2', '--python-2',
8098
help='[WARNING, EXPERIMENTAL] Turns on Python 2 mode,' +
8199
' needed when target file(s) are written in Python 2.', action='store_true')
@@ -150,11 +168,13 @@ def parse_args(args):
150168

151169
search_parser.add_argument('-sd', '--start-date',
152170
help='Start date for repo search. '
153-
'Criteria used is Created Date.', type=valid_date)
171+
'Criteria used is Created Date.',
172+
type=valid_date,
173+
default=date(2010, 1, 1))
154174
return parser.parse_args(args)
155175

156176

157-
def analyse_repo(github_repo, analysis_type):
177+
def analyse_repo(github_repo, analysis_type, ui_mode):
158178
cfg_list = list()
159179
directory = os.path.dirname(github_repo.path)
160180
project_modules = get_modules(directory)
@@ -170,42 +190,54 @@ def analyse_repo(github_repo, analysis_type):
170190

171191
initialize_constraint_table(cfg_list)
172192
analyse(cfg_list, analysis_type=analysis_type)
173-
vulnerability_log = find_vulnerabilities(cfg_list, analysis_type)
193+
vulnerability_log = find_vulnerabilities(
194+
cfg_list,
195+
analysis_type,
196+
ui_mode,
197+
VulnerabilityFiles(
198+
args.blackbox_mapping_file,
199+
args.trigger_word_file
200+
)
201+
)
174202
return vulnerability_log
175203

176204

177205
def main(command_line_args=sys.argv[1:]):
178206
args = parse_args(command_line_args)
179207

180-
analysis = None
208+
analysis = ReachingDefinitionsTaintAnalysis
181209
if args.liveness:
182210
analysis = LivenessAnalysis
183211
elif args.reaching:
184212
analysis = ReachingDefinitionsAnalysis
185-
elif args.reaching_taint:
186-
analysis = ReachingDefinitionsTaintAnalysis
187-
else:
188-
analysis = ReachingDefinitionsTaintAnalysis
213+
214+
ui_mode = UImode.NORMAL
215+
if args.interactive:
216+
ui_mode = UImode.INTERACTIVE
217+
elif args.trim_reassigned_in:
218+
ui_mode = UImode.TRIM
189219

190220
cfg_list = list()
191221
if args.git_repos:
192222
repos = get_repos(args.git_repos)
193223
for repo in repos:
194224
repo.clone()
195-
vulnerability_log = analyse_repo(repo, analysis)
225+
vulnerability_log = analyse_repo(repo, analysis, ui_mode)
196226
vulnerability_log.print_report()
197227
if not vulnerability_log.vulnerabilities:
198228
repo.clean_up()
199229
exit()
200230

201231
if args.which == 'search':
202232
set_github_api_token()
203-
if args.start_date:
204-
scan_github(args.search_string, args.start_date,
205-
analysis, analyse_repo, args.csv_path)
206-
else:
207-
scan_github(args.search_string, date(2010, 1, 1),
208-
analysis, analyse_repo, args.csv_path)
233+
scan_github(
234+
args.search_string,
235+
args.start_date,
236+
analysis,
237+
analyse_repo,
238+
args.csv_path,
239+
ui_mode
240+
)
209241
exit()
210242

211243
path = os.path.normpath(args.filepath)
@@ -221,6 +253,7 @@ def main(command_line_args=sys.argv[1:]):
221253
tree = generate_ast(path, python_2=args.python_2)
222254

223255
cfg_list = list()
256+
224257
interprocedural_cfg = interprocedural(
225258
tree,
226259
project_modules,
@@ -243,17 +276,15 @@ def main(command_line_args=sys.argv[1:]):
243276

244277
analyse(cfg_list, analysis_type=analysis)
245278

246-
vulnerability_log = None
247-
if args.trigger_word_file:
248-
vulnerability_log = find_vulnerabilities(cfg_list,
249-
analysis,
250-
args.trim_reassigned_in,
251-
args.trigger_word_file)
252-
else:
253-
vulnerability_log = find_vulnerabilities(cfg_list,
254-
analysis,
255-
args.trim_reassigned_in)
256-
279+
vulnerability_log = find_vulnerabilities(
280+
cfg_list,
281+
analysis,
282+
ui_mode,
283+
VulnerabilityFiles(
284+
args.blackbox_mapping_file,
285+
args.trigger_word_file
286+
)
287+
)
257288
vulnerability_log.print_report()
258289

259290
if args.draw_cfg:

‎pyt/argument_helpers.py‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
1+
import os
12
from argparse import ArgumentTypeError
3+
from collections import namedtuple
24
from datetime import datetime
5+
from enum import Enum
6+
7+
8+
default_blackbox_mapping_file = os.path.join(
9+
os.path.dirname(__file__),
10+
'vulnerability_definitions',
11+
'blackbox_mapping.json'
12+
)
13+
14+
15+
default_trigger_word_file = os.path.join(
16+
os.path.dirname(__file__),
17+
'vulnerability_definitions',
18+
'flask_trigger_words.pyt'
19+
)
320

421

522
def valid_date(s):
@@ -9,3 +26,18 @@ def valid_date(s):
926
except ValueError:
1027
msg = "Not a valid date: '{0}'. Format: {1}".format(s, date_format)
1128
raise ArgumentTypeError(msg)
29+
30+
31+
class UImode(Enum):
32+
INTERACTIVE = 0
33+
NORMAL = 1
34+
TRIM = 2
35+
36+
37+
VulnerabilityFiles = namedtuple(
38+
'VulnerabilityFiles',
39+
(
40+
'blackbox_mapping',
41+
'triggers'
42+
)
43+
)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /