find_vulnerabilities is what __main__.py calls, it takes a list of CFGs and returns a list of vulnerabilities.
The first thing we do is find all sources and sinks in the file, and then loop through each pair of source and sink to see if a source reaches a sink.
Once we obtain def-use chains, we find all of the paths from source to sink.
After we get each vulnerability chain, we see how_vulnerable it is
There are a few different vulnerability types used in how_vulnerable.
The hard-coded list of sources and sinks can be found in the vulnerability_definitions folder, currently all_trigger_words.pyt is used by default.
There are 3 kinds of vulnerabilities reported by PyT whose classes are defined in vulnerability_helper.py: regular, sanitised and unknown. We report a sanitised vulnerability when there is a known sanitiser between the source and sink, with confidence when the sanitiser is an assignment and with uncertainty if it is potentially sanitised by an if statement. Here is an example:
5 @app.route('/XSS_param', methods =['GET'])
6 def XSS1():
7 param = request.args.get('param', 'not set')
8 safe_param = Markup.escape(param)
9 html = open('templates/XSS_param.html').read()
10 resp = make_response(html.replace('{{ param }}', safe_param))
11 return respFile: examples/vulnerable_code/XSS_sanitised.py
> User input at line 7, source "request.args.get(":
~call_1 = ret_request.args.get('param', 'not set')
Reassigned in:
File: examples/vulnerable_code/XSS_sanitised.py
> Line 7: param = ~call_1
File: examples/vulnerable_code/XSS_sanitised.py
> Line 8: ~call_2 = ret_Markup.escape(param)
File: examples/vulnerable_code/XSS_sanitised.py
> Line 8: safe_param = ~call_2
File: examples/vulnerable_code/XSS_sanitised.py
> reaches line 10, sink "replace(":
~call_5 = ret_html.replace('{{ param }}', safe_param)
This vulnerability is sanitised by: Label: ~call_2 = ret_Markup.escape(param)and example code and output
Unknown and example code and output
How we find secondary nodes
How we find sources/sinks
How def-use chains are used h