Skip to content

Extend vulnerability location data with class #4024

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

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion tests/appsec/iast/sink/test_hardcoded_secrets.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def test_hardcoded_secrets_exec(self):
hardcode_secrets = [v for v in hardcode_secrets if v["evidence"]["value"] == "aws-access-token"]
assert len(hardcode_secrets) == 1
vuln = hardcode_secrets[0]
assert vuln["location"]["path"] == get_expectation(self.location_map)
assert vuln["location"]["class"] == get_expectation(self.location_map)


@features.iast_sink_hardcoded_secrets
Expand Down
54 changes: 42 additions & 12 deletions tests/appsec/iast/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,20 @@ def get_iast_event(request):
def assert_iast_vulnerability(
request, vulnerability_count=None, vulnerability_type=None, expected_location=None, expected_evidence=None
):
oldVersion = context.library < "[email protected]"
iast = get_iast_event(request=request)
assert iast["vulnerabilities"], "Expected at least one vulnerability"
vulns = iast["vulnerabilities"]
if vulnerability_type:
vulns = [v for v in vulns if v["type"] == vulnerability_type]
assert vulns, f"No vulnerability of type {vulnerability_type}"
if expected_location:
vulns = [v for v in vulns if v.get("location", {}).get("path", "") == expected_location]
vulns = [
v
for v in vulns
if (oldVersion and v.get("location", {}).get("path", "") == expected_location)
or (v.get("location", {}).get("class", "") == expected_location)
]
assert vulns, f"No vulnerability with location {expected_location}"
if expected_evidence:
vulns = [v for v in vulns if v.get("evidence", {}).get("value", "") == expected_evidence]
Expand Down Expand Up @@ -234,25 +240,49 @@ def validate_stack_traces(request):
assert "frames" in stack_trace, "'frames' not found in stack trace"
assert len(stack_trace["frames"]) <= 32, "stack trace above size limit (32 frames)"

# Vulns without location path are not expected to have a stack trace
# Vulns without location path/class are not expected to have a stack trace
old_version = context.library < "[email protected]"
location = vuln["location"]
assert location is not None, "This vulnerability is not expected to have a stack trace"
assert "path" in location, "This vulnerability is not expected to have a stack trace"
pathOrClass = "class"
if old_version:
pathOrClass = "path"

pathOrClassError = (
"This vulnerability was expected to have a "
+ pathOrClass
+ " in its location data, it is not possible to validate the stack trace"
)

assert location is not None, pathOrClassError
assert pathOrClass in location, pathOrClassError

locationFrame = None

for frame in stack_trace["frames"]:
# We are looking for the frame that corresponds to the location of the vulnerability, we will need to update this to cover all tracers
# currently support: Java, Python, Node.js
if (
stack_trace["language"] == "java"
and (
location["path"] in frame["class_name"]
and location["method"] in frame["function"]
and location["line"] == frame["line"]
(
stack_trace["language"] == "java"
and old_version
and (
location["path"] in frame["class_name"]
and location["method"] in frame["function"]
and location["line"] == frame["line"]
)
)
or (
stack_trace["language"] == "java"
and (
location["class"] in frame["class_name"]
and location["method"] in frame["function"]
and location["line"] == frame["line"]
)
)
or (
stack_trace["language"] in ("python", "nodejs")
and (frame.get("file", "").endswith(location["path"]) and location["line"] == frame["line"])
)
) or (
stack_trace["language"] in ("python", "nodejs")
and (frame.get("file", "").endswith(location["path"]) and location["line"] == frame["line"])
):
locationFrame = frame
assert locationFrame is not None, "location not found in stack trace"
Expand Down
Loading