Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UI] added trim option #47

Merged
merged 4 commits into from
Jun 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion pyt/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
action='store_true')
print_group.add_argument('-vp', '--verbose-print',
help='Verbose printing of -p.', action='store_true')
print_group.add_argument('-trim', '--trim-reassigned-in',
help='Trims the reassigned list to the vulnerability chain.', action='store_true')


parser.add_argument('-t', '--trigger-word-file',
help='Input trigger word file.', type=str)
Expand Down Expand Up @@ -217,9 +220,11 @@ def main():
vulnerability_log = None
if args.trigger_word_file:
vulnerability_log = find_vulnerabilities(cfg_list, analysis,
args.trim_reassigned_in,
args.trigger_word_file)
else:
vulnerability_log = find_vulnerabilities(cfg_list, analysis)
vulnerability_log = find_vulnerabilities(cfg_list, analysis,
args.trim_reassigned_in)

vulnerability_log.print_report()

Expand Down
61 changes: 47 additions & 14 deletions pyt/vulnerabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ def append(self, cfg_node):
elif not self.secondary_nodes:
self.secondary_nodes = [cfg_node]

def __repr__(self):
output = 'TriggerNode('

if self.trigger_word:
output = output + 'trigger_word is ' + str(self.trigger_word) + ', '

return (
output +
'sanitisers are ' + str(self.sanitisers) + ', '
'cfg_node is ' + str(self.cfg_node) + ')\n'
)


def identify_triggers(cfg, sources, sinks):
"""Identify sources, sinks and sanitisers in a CFG.
Expand Down Expand Up @@ -209,10 +221,10 @@ def get_sink_args(cfg_node):
return vv.result


def get_vulnerability(source, sink, triggers, lattice):
def get_vulnerability(source, sink, triggers, lattice, trim_reassigned_in):
"""Get vulnerability between source and sink if it exists.

Uses triggers to find sanitisers
Uses triggers to find sanitisers.

Args:
source(TriggerNode): TriggerNode of the source.
Expand All @@ -224,7 +236,8 @@ def get_vulnerability(source, sink, triggers, lattice):
"""
source_in_sink = lattice.in_constraint(source.cfg_node, sink.cfg_node)

secondary_in_sink = []
secondary_in_sink = list()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 :)


if source.secondary_nodes:
secondary_in_sink = [secondary for secondary in source.secondary_nodes
if lattice.in_constraint(secondary,
Expand All @@ -233,33 +246,50 @@ def get_vulnerability(source, sink, triggers, lattice):
trigger_node_in_sink = source_in_sink or secondary_in_sink

sink_args = get_sink_args(sink.cfg_node)
secondary_node_in_sink_args = None
if sink_args:
for node in secondary_in_sink:
if sink_args and node.left_hand_side in sink_args:
secondary_node_in_sink_args = node

trimmed_nodes = list()
if secondary_node_in_sink_args and trim_reassigned_in:
trimmed_nodes.append(secondary_node_in_sink_args)
node_in_the_vulnerability_chain = secondary_node_in_sink_args
# Here is where we do backwards slicing to traceback which nodes led to the vulnerability
for secondary in reversed(source.secondary_nodes):
if lattice.in_constraint(secondary, sink.cfg_node):
if secondary.left_hand_side in node_in_the_vulnerability_chain.right_hand_side_variables:
node_in_the_vulnerability_chain = secondary
trimmed_nodes.insert(0, node_in_the_vulnerability_chain)

source_lhs_in_sink_args = source.cfg_node.left_hand_side in sink_args\
if sink_args else None

secondary_nodes_in_sink_args = any(True for node in secondary_in_sink
if node.left_hand_side in sink_args)\
if sink_args else None
lhs_in_sink_args = source_lhs_in_sink_args or secondary_nodes_in_sink_args
lhs_in_sink_args = source_lhs_in_sink_args or secondary_node_in_sink_args

if trigger_node_in_sink and lhs_in_sink_args:
source_trigger_word = source.trigger_word
sink_trigger_word = sink.trigger_word
sink_is_sanitised = is_sanitized(sink, triggers.sanitiser_dict,
sink_is_sanitised = is_sanitized(sink,
triggers.sanitiser_dict,
lattice)

reassignment_nodes = source.secondary_nodes
if trimmed_nodes:
reassignment_nodes = trimmed_nodes
if sink_is_sanitised:
return SanitisedVulnerability(source.cfg_node, source_trigger_word,
sink.cfg_node, sink_trigger_word,
sink.sanitisers,
source.secondary_nodes)
reassignment_nodes)
else:
return Vulnerability(source.cfg_node, source_trigger_word,
sink.cfg_node, sink_trigger_word,
source.secondary_nodes)
reassignment_nodes)
return None


def find_vulnerabilities_in_cfg(cfg, vulnerability_log, definitions, lattice):
def find_vulnerabilities_in_cfg(cfg, vulnerability_log, definitions, lattice, trim_reassigned_in):
"""Find vulnerabilities in a cfg.

Args:
Expand All @@ -270,12 +300,13 @@ def find_vulnerabilities_in_cfg(cfg, vulnerability_log, definitions, lattice):
triggers = identify_triggers(cfg, definitions.sources, definitions.sinks)
for sink in triggers.sinks:
for source in triggers.sources:
vulnerability = get_vulnerability(source, sink, triggers, lattice)
vulnerability = get_vulnerability(source, sink, triggers, lattice, trim_reassigned_in)
if vulnerability:
vulnerability_log.append(vulnerability)


def find_vulnerabilities(cfg_list, analysis_type,
trim_reassigned_in=False,
trigger_word_file=default_trigger_word_file):
"""Find vulnerabilities in a list of CFGs from a trigger_word_file.

Expand All @@ -290,7 +321,9 @@ def find_vulnerabilities(cfg_list, analysis_type,
definitions = parse(trigger_word_file)

vulnerability_log = VulnerabilityLog()

for cfg in cfg_list:
find_vulnerabilities_in_cfg(cfg, vulnerability_log, definitions,
Lattice(cfg.nodes, analysis_type))
Lattice(cfg.nodes, analysis_type),
trim_reassigned_in)
return vulnerability_log
30 changes: 15 additions & 15 deletions pyt/vulnerability_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,45 +30,45 @@ def print_report(self):


class Reassigned():
def __init__(self, secondary_nodes):
self.secondary_nodes = secondary_nodes
def __init__(self, reassignment_nodes):
self.reassignment_nodes = reassignment_nodes

def __str__(self):
secondary = ''
if self.secondary_nodes:
secondary += '\nReassigned in: \n\t'
secondary += '\n\t'.join([
reassignment = ''
if self.reassignment_nodes:
reassignment += '\nReassigned in: \n\t'
reassignment += '\n\t'.join([
'File: ' + node.path + '\n\t' + ' > Line ' +
str(node.line_number) + ': ' +
node.label for node in self.secondary_nodes])
return secondary
node.label for node in self.reassignment_nodes])
return reassignment


class Vulnerability():
"""Vulnerability containing the source and the sources trigger word,
the sink and the sinks trigger word."""

def __init__(self, source, source_trigger_word,
sink, sink_trigger_word, secondary_nodes):
sink, sink_trigger_word, reassignment_nodes):
"""Set source and sink information."""
self.source = source
self.source_trigger_word = source_trigger_word
self.sink = sink
self.sink_trigger_word = sink_trigger_word
self.secondary_nodes = secondary_nodes
self.reassignment_nodes = reassignment_nodes

self.__remove_sink_from_secondary_nodes()

def __remove_sink_from_secondary_nodes(self):
if self.secondary_nodes:
if self.reassignment_nodes:
try:
self.secondary_nodes.remove(self.sink)
self.reassignment_nodes.remove(self.sink)
except ValueError:
pass

def __str__(self):
"""Pretty printing of a vulnerability."""
reassigned_str = Reassigned(self.secondary_nodes)
reassigned_str = Reassigned(self.reassignment_nodes)
return ('File: {}\n > User input at line {}, trigger word "{}":'
' \n\t{}{}\nFile: {}\n > reaches line {}, trigger word'
' "{}": \n\t{}'.format(
Expand All @@ -84,10 +84,10 @@ class SanitisedVulnerability(Vulnerability):
Also containing the sanitiser."""

def __init__(self, source, source_trigger_word,
sink, sink_trigger_word, sanitiser, secondary_nodes):
sink, sink_trigger_word, sanitiser, reassignment_nodes):
"""Set source, sink and sanitiser information."""
super().__init__(source, source_trigger_word,
sink, sink_trigger_word, secondary_nodes)
sink, sink_trigger_word, reassignment_nodes)
self.sanitiser = sanitiser

def __str__(self):
Expand Down