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

✨ implement progpilot SAST parser #10044 #10052

Merged
merged 13 commits into from
May 3, 2024
8 changes: 8 additions & 0 deletions docs/content/en/integrations/parsers/file/progpilot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: "Progpilot"
toc_hide: true
---
This parser imports the Progpilot SAST JSON output. The scanner can be found [here](https://github.com/designsecurity/progpilot).

### Sample Scan Data
Sample Progpilot Parser scans can be found [here](https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/progpilot).
1 change: 1 addition & 0 deletions dojo/tools/progpilot/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__author__ = "manuel-sommer"
80 changes: 80 additions & 0 deletions dojo/tools/progpilot/parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import json

from dojo.models import Finding


class ProgpilotParser:
def get_scan_types(self):
return ["Progpilot Scan"]

def get_label_for_scan_types(self, scan_type):
return "Progpilot Scan"

def get_description_for_scan_types(self, scan_type):
return "Progpilot JSON vulnerability report format."

def get_findings(self, filename, test):
findings = []
description = ""
results = json.load(filename)
for result in results:
source_name = result.get("source_name", None)
source_line = result.get("source_line", None)
source_column = result.get("source_column", None)
source_file = result.get("source_file", None)
tainted_flow = result.get("tainted_flow", None)
sink_name = result.get("sink_name", None)
sink_line = result.get("sink_line", None)
sink_column = result.get("sink_column", None)
sink_file = result.get("sink_file", None)
vuln_name = result.get("vuln_name", None)
vuln_cwe = result.get("vuln_cwe", None)
vuln_id = result.get("vuln_id", None)
vuln_type = result.get("vuln_type", None)
vuln_rule = result.get("vuln_rule", None)
vuln_line = result.get("vuln_line", None)
vuln_column = result.get("vuln_column", None)
vuln_file = result.get("vuln_file", None)
vuln_description = result.get("vuln_description", None)
description += "**vuln_type:** " + vuln_type + "\n"
if source_name is not None:
description += "**source_name:** " + str(source_name) + "\n"
if source_line is not None:
description += "**source_line:** " + str(source_line) + "\n"
if source_column is not None:
description += "**source_column:** " + str(source_column) + "\n"
if source_file is not None:
description += "**source_file:** " + str(source_file) + "\n"
if tainted_flow is not None:
description += "**tainted_flow:** " + str(tainted_flow) + "\n"
if sink_name is not None:
description += "**sink_name:** " + str(sink_name) + "\n"
if sink_column is not None:
description += "**sink_column:** " + str(sink_column) + "\n"
if vuln_rule is not None:
description += "**vuln_rule:** " + str(vuln_rule) + "\n"
if vuln_column is not None:
description += "**vuln_column:** " + str(vuln_column) + "\n"
if vuln_description is not None:
description += "**vuln_description:** " + str(vuln_description) + "\n"
find = Finding(
title=vuln_name,
test=test,
description=description,
severity="Medium",
dynamic_finding=False,
static_finding=True,
unique_id_from_tool=vuln_id
)
if sink_line is not None:
find.line = sink_line
elif vuln_line is not None:
find.line = vuln_line
if sink_file is not None:
find.file_path = sink_file
elif vuln_file is not None:
find.file_path = vuln_file
if vuln_cwe is not None:
find.cwe = int(vuln_cwe.split("CWE_")[1])
findings.append(find)
return findings
51 changes: 51 additions & 0 deletions unittests/scans/progpilot/progpilot.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
[
{
"source_name": [
"$sql"
],
"source_line": [
590
],
"source_column": [
25854
],
"source_file": [
"\/home\/kali\/Modules\/progpilot\/Order.php"
],
"tainted_flow": [
[
{
"flow_name": "$dni",
"flow_line": 588,
"flow_column": 25832,
"flow_file": "\/home\/User\/Modules\/progpilot\/Order.php"
},
{
"flow_name": "$getValue_return",
"flow_line": 565,
"flow_column": 25050,
"flow_file": "\/home\/User\/Modules\/progpilot\/Order.php"
}
]
],
"sink_name": "executeS",
"sink_line": 593,
"sink_column": 26002,
"sink_file": "\/home\/User\/Modules\/progpilot\/Order.php",
"vuln_name": "sql_injection",
"vuln_cwe": "CWE_89",
"vuln_id": "9c4f078e57a235d34183ddb1dd39ef8b91fc2eeed26718c5c5eb053874e401e6",
"vuln_type": "taint-style"
},
{
"vuln_rule": "MUST_VERIFY_DEFINITION",
"vuln_name": "security misconfiguration",
"vuln_line": 461,
"vuln_column": 18375,
"vuln_file": "\/home\/User\/Modules\/progpilot\/Order.php",
"vuln_description": "curl must verify that the certificate is trusted (CURLOPT_SSL_VERIFYPEER set to true)",
"vuln_cwe": "CWE_295",
"vuln_id": "797d1acd46cbf6305ec0a2480ed29414a76326bab6bebe533df8050f0205040d",
"vuln_type": "custom"
}
]
88 changes: 88 additions & 0 deletions unittests/scans/progpilot/progpilot2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
[
{
"source_name": [
"$json_encode_return"
],
"source_line": [
61
],
"source_column": [
1590
],
"source_file": [
"\/home\/User\/Modules\/progpilot\/ajax.php"
],
"tainted_flow": [
[
{
"flow_name": "$json_encode_param0_line61_column1590_progpilot",
"flow_line": 61,
"flow_column": 1590,
"flow_file": "\/home\/User\/Modules\/progpilot\/ajax.php"
},
{
"flow_name": "$response",
"flow_line": 59,
"flow_column": 1561,
"flow_file": "\/home\/User\/Modules\/progpilot\/ajax.php"
},
{
"flow_name": "$resp",
"flow_line": 26,
"flow_column": 765,
"flow_file": "\/home\/User\/Modules\/progpilot\/ajax.php"
},
{
"flow_name": "$validateAmount_return",
"flow_line": 26,
"flow_column": 773,
"flow_file": "\/home\/User\/Modules\/progpilot\/ajax.php"
},
{
"flow_name": "$validateAmount_param0_line26_column773_progpilot",
"flow_line": 26,
"flow_column": 773,
"flow_file": "\/home\/User\/Modules\/progpilot\/ajax.php"
},
{
"flow_name": "$vals",
"flow_line": 8,
"flow_column": 281,
"flow_file": "\/home\/User\/Modules\/progpilot\/ajax.php"
},
{
"flow_name": "$json_decode_return",
"flow_line": 8,
"flow_column": 289,
"flow_file": "\/home\/User\/Modules\/progpilot\/ajax.php"
},
{
"flow_name": "$json_decode_param0_line8_column289_progpilot",
"flow_line": 8,
"flow_column": 289,
"flow_file": "\/home\/User\/Modules\/progpilot\/ajax.php"
},
{
"flow_name": "$frontRequest",
"flow_line": 7,
"flow_column": 231,
"flow_file": "\/home\/User\/Modules\/progpilot\/ajax.php"
},
{
"flow_name": "$file_get_contents_return",
"flow_line": 7,
"flow_column": 247,
"flow_file": "\/home\/User\/Modules\/progpilot\/ajax.php"
}
]
],
"sink_name": "echo",
"sink_line": 61,
"sink_column": 1590,
"sink_file": "\/home\/kali\/Modules\/progpilot\/ajax.php",
"vuln_name": "xss",
"vuln_cwe": "CWE_79",
"vuln_id": "4c1c5e204a59146a9a046a6a49042ce9a26a7cfd952955ec8614a22b093e451d",
"vuln_type": "taint-style"
}
]
Loading
Loading