Skip to content

🔨 Merge the MobSF scanner #12501

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

Open
wants to merge 14 commits into
base: dev
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
title: "MobSF Scanner"
toc_hide: true
---
Export a JSON file using the API, api/v1/report\_json.
"Mobsfscan Scan" has been merged into the "MobSF Scan" parser. The "Mobsfscan Scan" scan_type has been retained to keep deduplication working for existing Tests, but users are encouraged to move to the "MobSF Scan" scan_type.

Export a JSON file using the API, api/v1/report\_json and import it to Defectdojo or import a JSON report from <https://github.com/MobSF/mobsfscan>

### Sample Scan Data
Sample MobSF Scanner scans can be found [here](https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/mobsf).

This file was deleted.

7 changes: 5 additions & 2 deletions docs/content/en/open_source/upgrading/2.48.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
title: 'Upgrading to DefectDojo Version 2.48.x'
toc_hide: true
weight: -20250602
description: Better pushing to JIRA for Finding Groups
description: MobSF parser merged, Better pushing to JIRA for Finding Groups
---

## Merge of MobSF parsers
"Mobsfscan Scan" has been merged into the "MobSF Scan" parser. The "Mobsfscan Scan" scan_type has been retained to keep deduplication working for existing Tests, but users are encouraged to move to the "MobSF Scan" scan_type.

## Finding Group JIRA Issue template changes
As part of [PR 12475](https://github.com/DefectDojo/django-DefectDojo/pull/12475) the [jira-finding-group-description.tpl](https://github.com/DefectDojo/django-DefectDojo/blob/master/dojo/templates/issue-trackers/jira_full/jira-finding-group-description.tpl) was updated. If you're using a custom set of JIRA template files, please review the PR for any changes you need to take into account.

There are no special instructions for upgrading to 2.48.x. Check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.48.0) for the contents of the release.
There are no special instructions for upgrading to 2.48.x. Check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.48.0) for the contents of the release.
2 changes: 1 addition & 1 deletion dojo/settings/settings.dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -1324,7 +1324,7 @@ def saml2_attrib_map_format(din):
"HCLAppScan XML": ["title", "description"],
"HCL AppScan on Cloud SAST XML": ["title", "file_path", "line", "severity"],
"KICS Scan": ["file_path", "line", "severity", "description", "title"],
"MobSF Scan": ["title", "description", "severity"],
"MobSF Scan": ["title", "description", "severity", "file_path"],
"MobSF Scorecard Scan": ["title", "description", "severity"],
"OSV Scan": ["title", "description", "severity"],
"Snyk Code Scan": ["vuln_id_from_tool", "file_path"],
Expand Down
388 changes: 388 additions & 0 deletions dojo/tools/mobsf/api_report_json.py

Large diffs are not rendered by default.

393 changes: 9 additions & 384 deletions dojo/tools/mobsf/parser.py

Large diffs are not rendered by default.

17 changes: 2 additions & 15 deletions dojo/tools/mobsfscan/parser.py → dojo/tools/mobsf/report.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import hashlib
import json
import re

from dojo.models import Finding


class MobsfscanParser:
class MobSFjsonreport:

"""A class that can be used to parse the mobsfscan (https://github.com/MobSF/mobsfscan) JSON report file."""

Expand All @@ -15,19 +14,7 @@ class MobsfscanParser:
"INFO": "Low",
}

def get_scan_types(self):
return ["Mobsfscan Scan"]

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

def get_description_for_scan_types(self, scan_type):
return "Import JSON report for mobsfscan report file."

def get_findings(self, filename, test):
data = json.load(filename)
if len(data.get("results")) == 0:
return []
def get_findings(self, data, test):
dupes = {}
for key, item in data.get("results").items():
metadata = item.get("metadata")
Expand Down
Empty file removed dojo/tools/mobsfscan/__init__.py
Empty file.
159 changes: 159 additions & 0 deletions unittests/tools/test_mobsf_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,162 @@ def test_parse_damnvulnrablebank(self):
findings = parser.get_findings(testfile, test)
testfile.close()
self.assertEqual(80, len(findings))

def test_parse_no_findings(self):
with (get_unit_tests_scans_path("mobsf") / "no_findings.json").open(encoding="utf-8") as testfile:
parser = MobSFParser()
findings = parser.get_findings(testfile, Test())
self.assertEqual(0, len(findings))

def test_parse_many_findings(self):
with (get_unit_tests_scans_path("mobsf") / "many_findings.json").open(encoding="utf-8") as testfile:
parser = MobSFParser()
findings = parser.get_findings(testfile, Test())
self.assertEqual(8, len(findings))

with self.subTest(i=0):
finding = findings[0]
self.assertEqual("android_certificate_transparency", finding.title)
self.assertEqual("Low", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(295, finding.cwe)
self.assertIsNotNone(finding.references)

with self.subTest(i=1):
finding = findings[1]
self.assertEqual("android_kotlin_hardcoded", finding.title)
self.assertEqual("Medium", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(798, finding.cwe)
self.assertIsNotNone(finding.references)
self.assertEqual("app/src/main/java/com/routes/domain/analytics/event/Signatures.kt", finding.file_path)
self.assertEqual(10, finding.line)

with self.subTest(i=2):
finding = findings[2]
self.assertEqual("android_kotlin_hardcoded", finding.title)
self.assertEqual("Medium", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(798, finding.cwe)
self.assertIsNotNone(finding.references)
self.assertEqual("app/src/main/java/com/routes/domain/analytics/event/Signatures2.kt", finding.file_path)
self.assertEqual(20, finding.line)

with self.subTest(i=3):
finding = findings[3]
self.assertEqual("android_prevent_screenshot", finding.title)
self.assertEqual("Low", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(200, finding.cwe)
self.assertIsNotNone(finding.references)

with self.subTest(i=4):
finding = findings[4]
self.assertEqual("android_root_detection", finding.title)
self.assertEqual("Low", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(919, finding.cwe)
self.assertIsNotNone(finding.references)

with self.subTest(i=5):
finding = findings[5]
self.assertEqual("android_safetynet", finding.title)
self.assertEqual("Low", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(353, finding.cwe)
self.assertIsNotNone(finding.references)

with self.subTest(i=6):
finding = findings[6]
self.assertEqual("android_ssl_pinning", finding.title)
self.assertEqual("Low", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(295, finding.cwe)
self.assertIsNotNone(finding.references)

with self.subTest(i=7):
finding = findings[7]
self.assertEqual("android_tapjacking", finding.title)
self.assertEqual("Low", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(200, finding.cwe)
self.assertIsNotNone(finding.references)

def test_parse_many_findings_cwe_lower(self):
with (get_unit_tests_scans_path("mobsf") / "many_findings_cwe_lower.json").open(encoding="utf-8") as testfile:
parser = MobSFParser()
findings = parser.get_findings(testfile, Test())
self.assertEqual(7, len(findings))

with self.subTest(i=0):
finding = findings[0]
self.assertEqual("android_certificate_transparency", finding.title)
self.assertEqual("Low", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(295, finding.cwe)
self.assertIsNotNone(finding.references)

with self.subTest(i=1):
finding = findings[1]
self.assertEqual("android_kotlin_hardcoded", finding.title)
self.assertEqual("Medium", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(798, finding.cwe)
self.assertIsNotNone(finding.references)
self.assertEqual("app/src/main/java/com/routes/domain/analytics/event/Signatures.kt", finding.file_path)
self.assertEqual(10, finding.line)

with self.subTest(i=2):
finding = findings[2]
self.assertEqual("android_prevent_screenshot", finding.title)
self.assertEqual("Low", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(200, finding.cwe)
self.assertIsNotNone(finding.references)

with self.subTest(i=3):
finding = findings[3]
self.assertEqual("android_root_detection", finding.title)
self.assertEqual("Low", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(919, finding.cwe)
self.assertIsNotNone(finding.references)

with self.subTest(i=4):
finding = findings[4]
self.assertEqual("android_safetynet", finding.title)
self.assertEqual("Low", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(353, finding.cwe)
self.assertIsNotNone(finding.references)

with self.subTest(i=5):
finding = findings[5]
self.assertEqual("android_ssl_pinning", finding.title)
self.assertEqual("Low", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(295, finding.cwe)
self.assertIsNotNone(finding.references)

with self.subTest(i=6):
finding = findings[6]
self.assertEqual("android_tapjacking", finding.title)
self.assertEqual("Low", finding.severity)
self.assertEqual(1, finding.nb_occurences)
self.assertIsNotNone(finding.description)
self.assertEqual(200, finding.cwe)
self.assertIsNotNone(finding.references)
Loading