-
Notifications
You must be signed in to change notification settings - Fork 182
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
Add feature to define findings manually in the model, similar to over… #180
base: master
Are you sure you want to change the base?
Changes from 5 commits
82bc106
9e0fce5
1eaeded
1640899
389ee11
05f6dfd
34959b6
f577e66
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,12 +59,18 @@ def __set__(self, instance, value): | |
# called when x.d = val | ||
# instance = x | ||
# value = val | ||
|
||
if instance in self.data: | ||
raise ValueError( | ||
"cannot overwrite {}.{} value with {}, already set to {}".format( | ||
instance, self.__class__.__name__, value, self.data[instance] | ||
if (not isinstance(instance, Finding) | ||
or (isinstance(instance, Finding) and isinstance(self,varString) and self.data[instance] != "invalid") | ||
or (isinstance(instance, Finding) and isinstance(self,varElement) and self.data[instance].name != "invalid") | ||
): | ||
raise ValueError( | ||
"cannot overwrite {}.{} value with {}, already set to {}".format( | ||
instance, self.__class__.__name__, value, self.data[instance] | ||
) | ||
) | ||
) | ||
|
||
self.data[instance] = value | ||
if self.onSet is not None: | ||
self.onSet(instance, value) | ||
|
@@ -603,17 +609,17 @@ class Finding: | |
"""Represents a Finding - the element in question | ||
and a description of the finding""" | ||
|
||
element = varElement(None, required=True, doc="Element this finding applies to") | ||
element = varElement(None, required=False, doc="Element this finding applies to") | ||
target = varString("", doc="Name of the element this finding applies to") | ||
description = varString("", required=True, doc="Threat description") | ||
details = varString("", required=True, doc="Threat details") | ||
severity = varString("", required=True, doc="Threat severity") | ||
mitigations = varString("", required=True, doc="Threat mitigations") | ||
example = varString("", required=True, doc="Threat example") | ||
severity = varString("", required=False, doc="Threat severity") | ||
mitigations = varString("", required=False, doc="Threat mitigations") | ||
example = varString("", required=False, doc="Threat example") | ||
id = varString("", required=True, doc="Finding ID") | ||
threat_id = varString("", required=True, doc="Threat ID") | ||
references = varString("", required=True, doc="Threat references") | ||
condition = varString("", required=True, doc="Threat condition") | ||
threat_id = varString("", required=False, doc="Threat ID") | ||
references = varString("", required=False, doc="Threat references") | ||
condition = varString("", required=False, doc="Threat condition") | ||
response = varString( | ||
"", | ||
required=False, | ||
|
@@ -626,6 +632,7 @@ class Finding: | |
""", | ||
) | ||
cvss = varString("", required=False, doc="The CVSS score and/or vector") | ||
source = varString("manual", required=False, doc="The source of the Finding.") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The name There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. I'll add some better text. I could remove the logic around source altogether and we just add it to every element in the threatlib. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's fine to have that logic, it's better to have this field only in |
||
|
||
def __init__( | ||
self, | ||
|
@@ -759,6 +766,16 @@ def resolve(self): | |
if not e.inScope: | ||
continue | ||
|
||
if (len(e.findings) > 0): | ||
|
||
for f in e.findings: | ||
finding_count += 1 | ||
f._safeset("id", str(finding_count)) | ||
f._safeset("element", e) | ||
f._safeset("target", e.name) | ||
findings.append(f) | ||
elements[e].append(f) | ||
|
||
override_ids = set(f.threat_id for f in e.overrides) | ||
# if element is a dataflow filter out overrides from source and sink | ||
# because they will be always applied there anyway | ||
|
@@ -774,13 +791,14 @@ def resolve(self): | |
continue | ||
|
||
finding_count += 1 | ||
f = Finding(e, id=str(finding_count), threat=t) | ||
f = Finding(e, id=str(finding_count), threat=t, source="pytm") | ||
logger.debug(f"new finding: {f}") | ||
findings.append(f) | ||
elements[e].append(f) | ||
|
||
self.findings = findings | ||
for e, findings in elements.items(): | ||
e.findings = findings | ||
e._safeset("findings", findings) | ||
|
||
def check(self): | ||
if self.description is None: | ||
|
@@ -1854,6 +1872,7 @@ def encode_threat_data(obj): | |
"threat_id", | ||
"references", | ||
"condition", | ||
"source", | ||
] | ||
|
||
if type(obj) is Finding or (len(obj) != 0 and type(obj[0]) is Finding): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -801,4 +801,4 @@ | |
"onDuplicates": "Action.NO_ACTION", | ||
"threatsExcluded": [], | ||
"threatsFile": "pytm/threatlib/threats.json" | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't remove end of line at end of file. Configure your text editor not to do that automatically. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I replaced the json using the produced json during the tests. I'm editing in vi so nothing is removed automatically on my end. If the space is important we could look to add it to the generated file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm against using special values like "invalid". Looks like we should not use this
var*
type forFindings
? What's exactly the purpose of these conditions?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
invalid was already there, I didn't remove it. It set when a Finding is created without and element, I dont think it ever happened before because the element was required but actually gets used now. The conditions are used to workaround the 'overwrite' protection. I wanted to narrow down the specific occurances where overwrite would be allowed and is only for Finding's element and target attributes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can avoid setting the findings two times? Can you locate the place where it's being set the second time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, cleaned things up. Instead of using setting the value to 'Element("invalid")' I set it to None and avoided the double set on the findings element and target attributes.