Skip to content
Open
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).
Expand Down
17 changes: 0 additions & 17 deletions docs/content/en/connecting_your_tools/parsers/file/mobsfscan.md

This file was deleted.

7 changes: 7 additions & 0 deletions docs/content/en/open_source/upgrading/2.51.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ This release introduces several important changes to the Helm chart configuratio

### Breaking changes

#### 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.

There are no special instructions for upgrading to 2.49.x. Check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.49.0) for the contents of the release.


#### Volume Management Improvements

- **Streamlined volume configuration**: The existing volume logic has been removed and replaced with more flexible `extraVolumes` and `extraVolumeMounts` options that provide deployment-agnostic volume management.
Expand Down
2 changes: 1 addition & 1 deletion dojo/settings/settings.dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -1333,7 +1333,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