Skip to content

Commit

Permalink
Handling "requires login" in "fingerprint" and "lines" fields of Semg…
Browse files Browse the repository at this point in the history
…rep JSON Report (issue #11480) (#11495)

* Update parser.py

* Update test_semgrep_parser.py

Unittest for handling "requires login"

* Add files via upload

Add example file for testing "requires login"

* Fingerprint Unittest

* handle requires login for "lines"

* Remove whitespaces from Blank Lines

* Fix AssertionError in unittest
  • Loading branch information
farsheedify authored Jan 15, 2025
1 parent 1849f9e commit cf0744a
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 0 deletions.
11 changes: 11 additions & 0 deletions dojo/tools/semgrep/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def get_findings(self, filename, test):

# fingerprint detection
unique_id_from_tool = item.get("extra", {}).get("fingerprint")
# treat "requires login" as if the fingerprint is absent
if unique_id_from_tool == "requires login":
unique_id_from_tool = None

if unique_id_from_tool:
finding.unique_id_from_tool = unique_id_from_tool

Expand Down Expand Up @@ -99,6 +103,10 @@ def get_findings(self, filename, test):

# fingerprint detection
unique_id_from_tool = item.get("extra", {}).get("fingerprint")
# treat "requires login" as if the fingerprint is absent
if unique_id_from_tool == "requires login":
unique_id_from_tool = None

if unique_id_from_tool:
finding.unique_id_from_tool = unique_id_from_tool

Expand Down Expand Up @@ -149,6 +157,9 @@ def get_description(self, item):
description += f"**Result message:** {message}\n"

snippet = item["extra"].get("lines")
if snippet == "requires login":
snippet = None # Treat "requires login" as no snippet

if snippet is not None:
if "<![" in snippet:
snippet = snippet.replace("<![", "<! [")
Expand Down
85 changes: 85 additions & 0 deletions unittests/scans/semgrep/fingerprint_test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"version": "1.100.0",
"results": [
{
"check_id": "python.lang.security.audit.dangerous-subprocess-use-tainted-env-args.dangerous-subprocess-use-tainted-env-args",
"path": "sample/brute.py",
"start": { "line": 31, "col": 29, "offset": 285 },
"end": { "line": 31, "col": 58, "offset": 314 },
"extra": {
"message": "Detected subprocess function 'run' with user controlled data. A malicious actor could leverage this to perform command injection. You may consider using 'shlex.quote()'.",
"metadata": {
"owasp": ["A01:2017 - Injection", "A03:2021 - Injection"],
"cwe": ["CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')"],
"asvs": {
"control_id": "5.3.8 OS Command Injection",
"control_url": "https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v53-output-encoding-and-injection-prevention-requirements",
"section": "V5: Validation, Sanitization and Encoding Verification Requirements",
"version": "4"
},
"references": [
"https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess",
"https://docs.python.org/3/library/subprocess.html",
"https://docs.python.org/3/library/shlex.html",
"https://semgrep.dev/docs/cheat-sheets/python-command-injection/"
],
"category": "security",
"technology": ["python"],
"confidence": "MEDIUM",
"cwe2022-top25": true,
"cwe2021-top25": true,
"subcategory": ["vuln"],
"likelihood": "MEDIUM",
"impact": "MEDIUM",
"vulnerability_class": ["Command Injection"],
"source": "https://semgrep.dev/r/python.lang.security.audit.dangerous-subprocess-use-tainted-env-args.dangerous-subprocess-use-tainted-env-args",
"shortlink": "https://sg.run/pLGg"
},
"severity": "ERROR",
"fingerprint": "requires login",
"lines": "requires login"
}
},
{
"check_id": "go.lang.security.audit.database.string-formatted-query.string-formatted-query",
"path": "sample/function.go",
"start": { "line": 37, "col": 2, "offset": 541 },
"end": { "line": 40, "col": 27, "offset": 722 },
"extra": {
"message": "String-formatted SQL query detected. This could lead to SQL injection if the string is not sanitized properly. Audit this call to ensure the SQL is not manipulable by external data.",
"metadata": {
"owasp": ["A01:2017 - Injection", "A03:2021 - Injection"],
"cwe": ["CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')"],
"references": ["https://owasp.org/Top10/A03_2021-Injection"],
"category": "security",
"technology": ["go"],
"confidence": "LOW",
"cwe2022-top25": true,
"cwe2021-top25": true,
"subcategory": ["audit"],
"likelihood": "LOW",
"impact": "HIGH",
"vulnerability_class": ["SQL Injection"],
"source": "https://semgrep.dev/r/go.lang.security.audit.database.string-formatted-query.string-formatted-query",
"shortlink": "https://sg.run/ydEr"
},
"severity": "WARNING",
"fingerprint": "requires login",
"lines": "requires login"
}
}
],
"errors": [],
"paths": {
"scanned": [
"README.md",
"sample/brute.py",
"sample/findmysecrets.go",
"sample/function.go",
"sample/go.mod",
"sample/session.go",
"sample/sqli.go"
]
},
"skipped_rules": []
}
12 changes: 12 additions & 0 deletions unittests/tools/test_semgrep_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,15 @@ def test_parse_sca_deployments_vulns(self):
self.assertEqual("requirements3.txt", finding.file_path)
self.assertEqual("222", finding.line)
self.assertEqual(617, finding.cwe)

def test_fingerprint_requires_login_and_null(self):
with open("unittests/scans/semgrep/fingerprint_test.json", encoding="utf-8") as testfile:
parser = SemgrepParser()
findings = parser.get_findings(testfile, Test())
self.assertEqual(2, len(findings))
self.assertEqual(None, findings[0].unique_id_from_tool)
self.assertEqual("sample/brute.py", findings[0].file_path)
self.assertEqual(31, findings[0].line)
self.assertEqual(None, findings[1].unique_id_from_tool)
self.assertEqual("sample/function.go", findings[1].file_path)
self.assertEqual(37, findings[1].line)

0 comments on commit cf0744a

Please sign in to comment.