Skip to content

🎉 Implement Cycognito parser #12558

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 6 commits into
base: dev
Choose a base branch
from

Conversation

manuel-sommer
Copy link
Contributor

Implement new parser for cycognito

Copy link

dryrunsecurity bot commented Jun 5, 2025

DryRun Security

This pull request contains minor configuration updates and test data for a CyCognito integration, with potential risks limited to test JSON files that should be carefully managed to prevent accidental information disclosure in production environments.

⚠️ Negligible Information Disclosure in dojo/settings/settings.dist.py
Vulnerability Negligible Information Disclosure
Description Adding 'Cycognito Scan' to a configuration dictionary is a standard integration practice. The tool name does not reveal sensitive information about the organization's infrastructure or security posture. This is not a meaningful security concern.

"Red Hat Satellite": ["description", "severity"],
"Qualys Hacker Guardian Scan": ["title", "severity", "description"],
"Cyberwatch scan (Galeax)": ["title", "description", "severity"],
"Cycognito Scan": ["title", "severity"],
}
# Override the hardcoded settings here via the env var

⚠️ Potential Description Rendering Bug in dojo/tools/cycognito/parser.py
Vulnerability Potential Description Rendering Bug
Description The code attempts to add 'affected_asset_tags' to the description, but currently uses an empty string. This appears to be a minor rendering bug rather than a security vulnerability. If sensitive information were present in the tags, it would simply not be displayed, which could be considered a display issue but not a security risk.

import json
from datetime import datetime
from dojo.models import Endpoint, Finding
class CycognitoParser:
def get_scan_types(self):
return ["Cycognito Scan"]
def get_label_for_scan_types(self, scan_type):
return "Cycognito Scan"
def get_description_for_scan_types(self, scan_type):
return "Support Cycognito issues from returned JSON over API."
def get_findings(self, file, test):
data = json.load(file)
findings = []
for vulnerability in data:
description = ""
mitigation = ""
impact = ""
confidence = vulnerability.get("confidence", None)
affected_asset = vulnerability.get("affected_asset", None)
package = vulnerability.get("package", None)
exploitation_availability = vulnerability.get("exploitation_availability", None)
tools = vulnerability.get("tools", None)
continent = vulnerability.get("continent", None)
references = vulnerability.get("references", None)
tech_owners = vulnerability.get("tech_owners", None)
teams = vulnerability.get("teams", None)
potential_threat = vulnerability.get("potential_threat", None)
attacker_interest = vulnerability.get("attacker_interest", None)
tags = vulnerability.get("tags", None)
base_severity_score = vulnerability.get("base_severity_score", None)
vulnid = vulnerability.get("id", None)
remediation_method = vulnerability.get("remediation_method", None)
issue_id = vulnerability.get("issue_id", None)
first_detected = vulnerability.get("first_detected", None)
summary = vulnerability.get("summary", None)
exploitation_complexity = vulnerability.get("exploitation_complexity", None)
underground_activity = vulnerability.get("underground_activity", None)
resolved_at = vulnerability.get("resolved_at", None)
snooze_expiration = vulnerability.get("snooze_expiration", None)
attractiveness_label = vulnerability.get("attractiveness_label", None)
affected_ptr_domains = vulnerability.get("affected_ptr_domains", None)
affected_asset_tags = vulnerability.get("affected_asset_tags", None)
advisories = vulnerability.get("advisories", None)
environments = vulnerability.get("environments", None)
locations = vulnerability.get("locations", None)
region = vulnerability.get("region", None)
detection_complexity = vulnerability.get("detection_complexity", None)
port = vulnerability.get("port", None)
remediation_effort = vulnerability.get("remediation_effort", None)
exploitation_method = vulnerability.get("exploitation_method", None)
attractiveness = vulnerability.get("attractiveness", None)
title = vulnerability.get("title", None)
platforms = vulnerability.get("platforms", None)
exploitation_score = vulnerability.get("exploitation_score", None)
base_severity = vulnerability.get("base_severity", None)
issue_type = vulnerability.get("issue_type", None)
organizations = vulnerability.get("organizations", None)
business_units = vulnerability.get("business_units", None)
cve_ids = vulnerability.get("cve_ids", None)
comment = vulnerability.get("comment", None)
evidence = vulnerability.get("evidence", None)
remediation_steps = vulnerability.get("remediation_steps", None)
potential_impact = vulnerability.get("potential_impact", None)
if confidence is not None:
description += "**confidence:** " + str(confidence) + "\n"
if affected_asset is not None:
description += "**affected_asset:** " + str(affected_asset) + "\n"
if package is not None:
description += "**package:** " + str(package) + "\n"
if exploitation_availability is not None and not "None":
description += "**exploitation_availability:** " + str(exploitation_availability) + "\n"
if tools and tools is not None:
description += "**tools:** " + str(tools) + "\n"
if continent and continent is not None:
description += "**continent:** " + str(", ".join(continent)) + "\n"
if tech_owners and tech_owners is not None:
description += "**tech_owners:** " + str(tech_owners) + "\n"
if teams and teams is not None:
description += "**teams:** " + str(teams) + "\n"
if potential_threat and potential_threat is not None:
description += "**potential_threat:** " + str(potential_threat) + "\n"
if attacker_interest is not None and not "None":
description += "**attacker_interest:** " + str(attacker_interest) + "\n"
if tags and tags is not None:
description += "**tags:** " + str(tags) + "\n"
if base_severity_score is not None:
description += "**base_severity_score:** " + str(base_severity_score) + "\n"
if vulnid is not None:
description += "**id:** " + str(vulnid) + "\n"
if remediation_method is not None:
mitigation += "**remediation_method:** " + str(remediation_method) + "\n"
if issue_id is not None:
description += "**issue_id:** " + str(issue_id) + "\n"
if summary is not None:
description += "**summary:** " + str(summary) + "\n"
if exploitation_complexity is not None and exploitation_complexity != "unknown":
description += "**exploitation_complexity:** " + str(exploitation_complexity) + "\n"
if underground_activity is not None:
description += "**underground_activity:** " + str(underground_activity) + "\n"
if resolved_at is not None:
description += "**resolved_at:** " + str(resolved_at) + "\n"
if snooze_expiration is not None:
description += "**snooze_expiration:** " + str(snooze_expiration) + "\n"
if attractiveness_label is not None:
description += "**attractiveness_label:** " + str(attractiveness_label) + "\n"
if affected_ptr_domains and affected_ptr_domains is not None:
description += "**affected_ptr_domains:** " + str(", ".join(affected_ptr_domains)) + "\n"
if affected_asset_tags and affected_asset_tags is not None:
description += "**affected_asset_tags:** " + "" + "\n"
if advisories and advisories is not None:
description += "**advisories:** " + str(advisories) + "\n"
if environments and environments is not None:
description += "**environments:** " + str(", ".join(environments)) + "\n"
if locations and locations is not None:
description += "**locations:** " + str(", ".join(locations)) + "\n"
if region and region is not None:
description += "**region:** " + str(", ".join(region)) + "\n"
if detection_complexity is not None:
description += "**detection_complexity:** " + str(detection_complexity) + "\n"
if port is not None:
description += "**port:** " + str(port) + "\n"
if remediation_effort is not None:
mitigation += "**remediation_effort:** " + str(remediation_effort) + "\n"
if exploitation_method is not None and exploitation_method != "unknown":
description += "**exploitation_method:** " + str(exploitation_method) + "\n"
if attractiveness is not None:
description += "**attractiveness:** " + str(attractiveness) + "\n"
if platforms is not None:
description += "**platforms:** " + str(", ".join(platforms)) + "\n"
if exploitation_score is not None:
description += "**exploitation_score:** " + str(exploitation_score) + "\n"
if issue_type is not None:
description += "**issue_type:** " + str(issue_type) + "\n"
if organizations is not None:
description += "**organizations:** " + str(", ".join(organizations)) + "\n"
if business_units is not None:
description += "**business_units:** " + str(", ".join(business_units)) + "\n"
if comment is not None:
description += "**comment:** " + str(comment) + "\n"
if evidence is not None:
description += "**evidence:** " + str(evidence) + "\n"
if remediation_steps is not None:
mitigation += "**remediation_steps:** " + str("\n ".join(remediation_steps)) + "\n"
if potential_impact and potential_impact is not None:
impact = "**potential_impact:** " + str(", ".join(potential_impact)) + "\n"
finding = Finding(
title=title,
test=test,
description=description,
severity=base_severity.capitalize(),
references=str("\n".join(references)),
date=datetime.strptime(first_detected, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d"),
dynamic_finding=True,
mitigation=mitigation,
impact=impact,
)
if cve_ids and cve_ids is not None:
finding.unsaved_vulnerability_ids = []
for cve_id in cve_ids:
finding.unsaved_vulnerability_ids.append(cve_id)
finding.unsaved_endpoints = []
finding.unsaved_endpoints.append(Endpoint(host=affected_asset.replace("ip/", "").replace("webapp/", "").replace("cert/", "").replace("domain/", "")))
findings.append(finding)
return findings

⚠️ Low-Impact URL Reference in docs/content/en/connecting_your_tools/parsers/file/cycognito.md
Vulnerability Low-Impact URL Reference
Description The documentation file contains a GitHub repository link for sample scan data. This is a standard practice for providing reference materials and does not constitute a significant security risk. The link points to the project's own repository, and there's no evidence of potential domain squatting or malicious content manipulation.

---
title: "Cycognito"
toc_hide: true
---
Import report in JSON returned from Cycognito API.
### Sample Scan Data
Sample Cycognito scans can be found [here](https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/cycognito).

⚠️ Sensitive Test Data Exposure in unittests/scans/cycognito/many_vuln.json
Vulnerability Sensitive Test Data Exposure
Description The JSON file contains detailed vulnerability information including internal identifiers, CVE IDs, and network details. While this is a unit test file, care should be taken to ensure it is not accidentally deployed to production or publicly accessible locations. The file should be clearly marked as test data and kept within the test environment.

[
{
"compliance_violations": [
"NIST-800-171",
"CIS",
"PCI-DSS",
"NIST-800-53",
"ISO27002"
],
"confidence": 30,
"mitre_attack_next_technique_name": "Credential Access: Network Sniffing",
"affected_asset": "domain/asdf.com",
"package": "ASM",
"cis_controls": [
"7.6",
"16.4",
"16.5",
"18.2",
"7.5",
"7.4"
],
"exploitation_availability": "None",
"tools": [],
"last_detected": "2025-05-16T00:37:19.000Z",
"continent": [
"America"
],
"references": [
"https://dheatattack.gitlab.io/",
"https://github.com/c0r0n3r/dheater"
],
"tech_owners": [],
"teams": [],
"potential_threat": "Vulnerable Software",
"attacker_interest": "None",
"tags": [],
"nist_800_171_controls": [
"3.3.5",
"3.12.2",
"3.13.8",
"3.14.1",
"3.14.6",
"3.11.3"
],
"base_severity_score": 7.5,
"id": "issue/1.2.3.4",
"mitre_attack_technique_name": "Credential Access: Adversary-in-the-Middle",
"revalidation_requested": false,
"nist_800_53_controls": [
"AC-17(2)",
"AC-17(9)",
"CM-8",
"SI-2(3)",
"SI-2(5)"
],
"issue_status": "new",
"iso27001_controls": [],
"is_snoozed": false,
"remediation_method": "Patch",
"severity_change_reason": null,
"issue_id": "Wasfdwfewef",
"first_detected": "2025-05-16T00:37:19.000Z",
"mitre_attack_next_technique_subtitle": "Network Sniffing",
"summary": "The remote SSH server is supporting Diffie-Hellman ephemeral\n (DHE) Key Exchange (KEX) algorithms and thus could be prone to a denial of service (DoS)\n vulnerability.\n",
"exploitation_complexity": "unknown",
"underground_activity": null,
"enhanced_severity": "medium",
"resolved_at": null,
"snooze_expiration": null,
"attractiveness_label": "extreme",
"investigation_status": "uninvestigated",
"affected_ptr_domains": [],
"affected_asset_tags": [],
"enhanced_severity_score": 6.0,
"severity_score": 7.5,
"advisories": [],
"environments": [
"Cryptographic Protocols",
"FTP Servers",
"Remote Connection"
],
"revalidation_request_time": null,
"locations": [
"USA"
],
"region": [
"Central America"
],
"issue_types": [
"Cryptographic Vulnerability"
],
"detection_complexity": "Service Detection",
"mitre_attack_technique_title": "Credential Access",
"port": 22,
"remediation_effort": "medium",
"exploitation_method": "unknown",
"attractiveness": 4.0,
"title": "Diffie-Hellman Ephemeral Key Exchange DoS Vulnerability (SSH, D(HE)ater)",
"platforms": [
"FTP Protocol",
"OpenSSH",
"SSH Protocol",
"TLS Protocol",
"VSFTPD FTP Server"
],
"exploitation_score": 0,
"comments": [],
"base_severity": "medium",
"issue_type": "Cryptographic Vulnerability",
"organizations": [
"organization"
],
"mitre_attack_next_technique_title": "Credential Access",
"business_units": [
"business-unit/it"
],
"mitre_attack_technique_subtitle": "Adversary-in-the-Middle",
"investigating_since": null,
"asset_status": "new",
"cve_ids": [
"CVE-2024-41996",
"CVE-2022-40735",
"CVE-2002-20001"
],
"comment": null,
"severity": "medium",
"evidence": {
"evidence": "The remote SSH server supports the following DHE KEX algorithm(s):\n\ndiffie-hellman-group1-sha1\ndiffie-hellman-group14-sha1\ndiffie-hellman-group14-sha256\ndiffie-hellman-group16-sha512\ndiffie-hellman-group18-sha512\ndiffie-hellman-group-exchange-sha1\ndiffie-hellman-group-exchange-sha256\n",
"more-details-link": "",
"curl-cmd": "",
"hostname": "1.2.3.4"
},
"iso27002_controls": [
"5.9",
"8.16",
"8.15",
"8.8"
],
"remediation_steps": [
"- DHE key exchange should be disabled if no other mitigation\n mechanism can be used and either elliptic-curve variant of Diffie-Hellman (ECDHE) or RSA key\n exchange is supported by the clients. The fact that RSA key exchange is not forward secret should\n be considered.\n\n - Limit the maximum number of concurrent connections in e.g. the configuration of the remote\n server. For OpenSSH this limit can be configured via the 'MaxStartups' option, for other products\n please refer to the manual of the product in question on configuration possibilities."
],
"potential_impact": [],
"pci_dss_controls": [
"10.2.1",
"10.4.1",
"6.4.1",
"11.4.3"
]
},
{
"compliance_violations": [
"NIST-800-171",
"NIST-800-53",
"ISO27002"
],
"confidence": 30,
"mitre_attack_next_technique_name": "Credential Access: Network Sniffing",
"affected_asset": "cert/fjwfjewiofjweofijewoifj0oi",
"package": "ASM",
"cis_controls": [
"7.6",
"3.11",
"7.5",
"16.7"
],
"exploitation_availability": "None",
"tools": [],
"last_detected": "2025-05-16T00:37:19.000Z",
"continent": [
"America"
],
"references": [
"https://dheatattack.gitlab.io/",
"https://github.com/Balasys/dheater",
"https://github.com/c0r0n3r/dheater"
],
"tech_owners": [],
"teams": [],
"potential_threat": "Vulnerable Software",
"attacker_interest": "None",
"tags": [],
"nist_800_171_controls": [
"3.3.5",
"3.12.2",
"3.11.2",
"3.3.3",
"3.14.7",
"3.3.1",
"3.3.2",
"3.1.11",
"3.12.1",
"3.14.1",
"3.14.6",
"3.11.3"
],
"base_severity_score": 7.5,
"id": "issue/12.3.4.5-wld-o-",
"mitre_attack_technique_name": "Credential Access: Adversary-in-the-Middle",
"revalidation_requested": false,
"nist_800_53_controls": [
"AC-17(2)",
"AC-17(9)",
"CM-8",
"SI-4(2)",
"SI-4(12)",
"SC-5",
"AU-2",
"AU-6",
"AC-17(1)",
"SI-4(5)"
],
"issue_status": "new",
"iso27001_controls": [],
"is_snoozed": false,
"remediation_method": "Patch",
"severity_change_reason": null,
"issue_id": "WLD-O-fwefe",
"first_detected": "2025-05-16T00:37:19.000Z",
"mitre_attack_next_technique_subtitle": "Network Sniffing",
"summary": "The remote SSL/TLS server is supporting Diffie-Hellman ephemeral\n (DHE) Key Exchange algorithms and thus could be prone to a denial of service (DoS)\n vulnerability.\n",
"exploitation_complexity": "unknown",
"underground_activity": null,
"enhanced_severity": "medium",
"resolved_at": null,
"snooze_expiration": null,
"attractiveness_label": "extreme",
"investigation_status": "uninvestigated",
"affected_ptr_domains": [],
"affected_asset_tags": [],
"enhanced_severity_score": 6.0,
"severity_score": 7.5,
"advisories": [],
"environments": [
"Cryptographic Protocols",
"FTP Servers",
"Remote Connection"
],
"revalidation_request_time": null,
"locations": [
"DEU"
],
"region": [
"Western Europe"
],
"issue_types": [
"Cryptographic Vulnerability"
],
"detection_complexity": "Service Detection",
"mitre_attack_technique_title": "Credential Access",
"port": 21,
"remediation_effort": "medium",
"exploitation_method": "unknown",
"attractiveness": 4.0,
"title": "Diffie-Hellman Ephemeral Key Exchange DoS Vulnerability (SSL/TLS, D(HE)ater)",
"platforms": [
"FTP Protocol",
"OpenSSH",
"SSH Protocol",
"TLS Protocol",
"VSFTPD FTP Server"
],
"exploitation_score": 0,
"comments": [],
"base_severity": "medium",
"issue_type": "Cryptographic Vulnerability",
"organizations": [
"organization"
],
"mitre_attack_next_technique_title": "Credential Access",
"business_units": [
"business-unit/it"
],
"mitre_attack_technique_subtitle": "Adversary-in-the-Middle",
"investigating_since": null,
"asset_status": "new",
"cve_ids": [
"CVE-2024-41996",
"CVE-2022-40735",
"CVE-2002-20001"
],
"comment": null,
"severity": "medium",
"evidence": {
"evidence": "'DHE' cipher suites accepted by this service via the TLSv1.2 protocol:\n\nTLS_DHE_RSA_WITH_AES_128_CBC_SHA\nTLS_DHE_RSA_WITH_AES_128_CBC_SHA256\nTLS_DHE_RSA_WITH_AES_128_GCM_SHA256\nTLS_DHE_RSA_WITH_AES_256_CBC_SHA\nTLS_DHE_RSA_WITH_AES_256_CBC_SHA256\nTLS_DHE_RSA_WITH_AES_256_GCM_SHA384\nTLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA\nTLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA\n\n\n",
"more-details-link": "",
"curl-cmd": "",
"hostname": "2.3.4.5"
},
"iso27002_controls": [
"5.9",
"8.16",
"8.15",
"8.8"
],
"remediation_steps": [
"- DHE key exchange should be disabled if no other mitigation\n mechanism can be used and either elliptic-curve variant of Diffie-Hellman (ECDHE) or RSA key\n exchange is supported by the clients. The fact that RSA key exchange is not forward secret should\n be considered.\n\n - Limit the maximum number of concurrent connections in e.g. the configuration of the remote\n server. For Postfix this limit can be configured via 'smtpd_client_new_tls_session_rate_limit'\n option, for other products please refer to the manual of the product in question on configuration\n possibilities."
],
"potential_impact": [],
"pci_dss_controls": [
"6.4.1",
"1.2.6",
"6.3.3",
"11.4.3"
]
},
{
"compliance_violations": [
"NIST-800-171",
"CIS",
"ISO27002"
],
"confidence": 30,
"mitre_attack_next_technique_name": "Credential Access: Network Sniffing",
"affected_asset": "webapp/afe.com",
"package": "ASM",
"cis_controls": [
"7.6",
"16.4",
"16.5",
"18.2",
"7.5",
"7.4"
],
"exploitation_availability": "None",
"tools": [],
"last_detected": "2025-05-15T17:10:37.000Z",
"continent": [
"America"
],
"references": [
"https://dheatattack.gitlab.io/",
"https://dheatattack.gitlab.io/details/",
"https://github.com/c0r0n3r/dheater"
],
"tech_owners": [],
"teams": [],
"potential_threat": "Vulnerable Software",
"attacker_interest": "None",
"tags": [],
"nist_800_171_controls": [
"3.3.5",
"3.12.2",
"3.11.2",
"3.1.12",
"3.14.6",
"3.11.3"
],
"base_severity_score": 7.5,
"id": "issue/2.3.45-o-",
"mitre_attack_technique_name": "Credential Access: Adversary-in-the-Middle",
"revalidation_requested": false,
"nist_800_53_controls": [
"AC-17(2)",
"AC-17(9)",
"CM-8",
"SI-2(3)",
"SI-4(16)",
"SI-2(6)",
"SC-7",
"AU-14",
"SI-2(5)",
"AC-17",
"CM-6",
"RA-5",
"AC-17(5)",
"SI-2(4)",
"SI-4(2)",
"SI-4(12)",
"SC-5",
"AU-2",
"AU-6",
"AC-17(1)",
"SI-4(5)"
],
"issue_status": "new",
"iso27001_controls": [],
"is_snoozed": false,
"remediation_method": "Patch",
"severity_change_reason": null,
"issue_id": "WLD-O-",
"first_detected": "2025-05-15T17:10:37.000Z",
"mitre_attack_next_technique_subtitle": "Network Sniffing",
"summary": "The remote SSH server is supporting Diffie-Hellman ephemeral\n (DHE) Key Exchange (KEX) algorithms and thus could be prone to a denial of service (DoS)\n vulnerability.\n",
"exploitation_complexity": "unknown",
"underground_activity": null,
"enhanced_severity": "medium",
"resolved_at": null,
"snooze_expiration": null,
"attractiveness_label": "extreme",
"investigation_status": "uninvestigated",
"affected_ptr_domains": [],
"affected_asset_tags": [],
"enhanced_severity_score": 6.0,
"severity_score": 7.5,
"advisories": [],
"environments": [
"Remote Connection"
],
"revalidation_request_time": null,
"locations": [
"fasadf"
],
"region": [
"USA"
],
"issue_types": [
"Cryptographic Vulnerability"
],
"detection_complexity": "Service Detection",
"mitre_attack_technique_title": "Credential Access",
"port": 22,
"remediation_effort": "medium",
"exploitation_method": "unknown",
"attractiveness": 4.0,
"title": "Diffie-Hellman Ephemeral Key Exchange DoS Vulnerability (SSH, D(HE)ater)",
"platforms": [
"OpenSSH",
"SSH Protocol"
],
"exploitation_score": 0,
"comments": [],
"base_severity": "medium",
"issue_type": "Cryptographic Vulnerability",
"organizations": [
"organization"
],
"mitre_attack_next_technique_title": "Credential Access",
"business_units": [
"business-unit/it"
],
"mitre_attack_technique_subtitle": "Adversary-in-the-Middle",
"investigating_since": null,
"asset_status": "new",
"cve_ids": [
"CVE-2024-41996",
"CVE-2022-40735",
"CVE-2002-20001"
],
"comment": null,
"severity": "medium",
"evidence": {
"evidence": "The remote SSH server supports the following DHE KEX algorithm(s):\n\ndiffie-hellman-group1-sha1\ndiffie-hellman-group14-sha1\ndiffie-hellman-group14-sha256\ndiffie-hellman-group16-sha512\ndiffie-hellman-group18-sha512\ndiffie-hellman-group-exchange-sha1\ndiffie-hellman-group-exchange-sha256\n",
"more-details-link": "",
"curl-cmd": "",
"hostname": "2.3.4.5"
},
"iso27002_controls": [
"5.9",
"8.16",
"8.15",
"8.8"
],
"remediation_steps": [
"- DHE key exchange should be disabled if no other mitigation\n mechanism can be used and either elliptic-curve variant of Diffie-Hellman (ECDHE) or RSA key\n exchange is supported by the clients. The fact that RSA key exchange is not forward secret should\n be considered.\n\n - Limit the maximum number of concurrent connections in e.g. the configuration of the remote\n server. For OpenSSH this limit can be configured via the 'MaxStartups' option, for other products\n please refer to the manual of the product in question on configuration possibilities."
],
"potential_impact": [],
"pci_dss_controls": [
"10.2.1",
"10.4.1",
"6.4.1",
"1.2.6",
"6.3.2",
"11.4.3"
]
}
]

⚠️ Sensitive Vulnerability Test Data in unittests/scans/cycognito/one_vuln.json
Vulnerability Sensitive Vulnerability Test Data
Description Similar to hunk_id 6, this is a unit test JSON file containing detailed vulnerability information. It should be treated as test data and kept strictly within the testing environment to prevent potential information disclosure.

[
{
"compliance_violations": [
"NIST-800-171",
"CIS",
"ISO27002"
],
"confidence": 30,
"mitre_attack_next_technique_name": "Credential Access: Network Sniffing",
"affected_asset": "ip/2.3.4.5",
"package": "ASM",
"cis_controls": [
"7.6",
"16.4",
"16.5",
"18.2",
"7.5",
"7.4"
],
"exploitation_availability": "None",
"tools": [],
"last_detected": "2025-05-15T17:10:37.000Z",
"continent": [
"America"
],
"references": [
"https://dheatattack.gitlab.io/"
],
"tech_owners": [],
"teams": [],
"potential_threat": "Vulnerable Software",
"attacker_interest": "None",
"tags": [],
"nist_800_171_controls": [
"3.3.5",
"3.12.2",
"3.11.2",
"3.1.12",
"3.14.6",
"3.11.3"
],
"base_severity_score": 7.5,
"id": "issue/2.3.45-o-",
"mitre_attack_technique_name": "Credential Access: Adversary-in-the-Middle",
"revalidation_requested": false,
"nist_800_53_controls": [
"AC-17(2)",
"AC-17(9)",
"CM-8",
"SI-2(3)",
"SI-4(16)",
"SI-2(6)",
"SC-7",
"AU-14",
"SI-2(5)",
"AC-17",
"CM-6",
"RA-5",
"AC-17(5)",
"SI-2(4)",
"SI-4(2)",
"SI-4(12)",
"SC-5",
"AU-2",
"AU-6",
"AC-17(1)",
"SI-4(5)"
],
"issue_status": "new",
"iso27001_controls": [],
"is_snoozed": false,
"remediation_method": "Patch",
"severity_change_reason": null,
"issue_id": "WLD-O-",
"first_detected": "2025-05-15T17:10:37.000Z",
"mitre_attack_next_technique_subtitle": "Network Sniffing",
"summary": "The remote SSH server is supporting Diffie-Hellman ephemeral\n (DHE) Key Exchange (KEX) algorithms and thus could be prone to a denial of service (DoS)\n vulnerability.\n",
"exploitation_complexity": "unknown",
"underground_activity": null,
"enhanced_severity": "medium",
"resolved_at": null,
"snooze_expiration": null,
"attractiveness_label": "extreme",
"investigation_status": "uninvestigated",
"affected_ptr_domains": [],
"affected_asset_tags": [],
"enhanced_severity_score": 6.0,
"severity_score": 7.5,
"advisories": [],
"environments": [
"Remote Connection"
],
"revalidation_request_time": null,
"locations": [
"fasadf"
],
"region": [
"USA"
],
"issue_types": [
"Cryptographic Vulnerability"
],
"detection_complexity": "Service Detection",
"mitre_attack_technique_title": "Credential Access",
"port": 22,
"remediation_effort": "medium",
"exploitation_method": "unknown",
"attractiveness": 4.0,
"title": "Diffie-Hellman Ephemeral Key Exchange DoS Vulnerability (SSH, D(HE)ater)",
"platforms": [
"OpenSSH",
"SSH Protocol"
],
"exploitation_score": 0,
"comments": [],
"base_severity": "medium",
"issue_type": "Cryptographic Vulnerability",
"organizations": [
"organization"
],
"mitre_attack_next_technique_title": "Credential Access",
"business_units": [
"business-unit/it"
],
"mitre_attack_technique_subtitle": "Adversary-in-the-Middle",
"investigating_since": null,
"asset_status": "new",
"cve_ids": [
"CVE-2024-41996",
"CVE-2022-40735",
"CVE-2002-20001"
],
"comment": null,
"severity": "medium",
"evidence": {
"evidence": "The remote SSH server supports the following DHE KEX algorithm(s):\n\ndiffie-hellman-group1-sha1\ndiffie-hellman-group14-sha1\ndiffie-hellman-group14-sha256\ndiffie-hellman-group16-sha512\ndiffie-hellman-group18-sha512\ndiffie-hellman-group-exchange-sha1\ndiffie-hellman-group-exchange-sha256\n",
"more-details-link": "",
"curl-cmd": "",
"hostname": "2.3.4.5"
},
"iso27002_controls": [
"5.9",
"8.16",
"8.15",
"8.8"
],
"remediation_steps": [
"- DHE key exchange should be disabled if no other mitigation\n mechanism can be used and either elliptic-curve variant of Diffie-Hellman (ECDHE) or RSA key\n exchange is supported by the clients. The fact that RSA key exchange is not forward secret should\n be considered.\n\n - Limit the maximum number of concurrent connections in e.g. the configuration of the remote\n server. For OpenSSH this limit can be configured via the 'MaxStartups' option, for other products\n please refer to the manual of the product in question on configuration possibilities."
],
"potential_impact": [],
"pci_dss_controls": [
"10.2.1",
"10.4.1",
"6.4.1",
"1.2.6",
"6.3.2",
"11.4.3"
]
}
]


All finding details can be found in the DryRun Security Dashboard.

@github-actions github-actions bot added settings_changes Needs changes to settings.py based on changes in settings.dist.py included in this PR docs unittests parser labels Jun 5, 2025
Copy link
Contributor

@mtesauro mtesauro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved

@manuel-sommer manuel-sommer requested a review from Maffooch June 6, 2025 19:12
Copy link
Member

@valentijnscholten valentijnscholten left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does one generate a report from the Cycognito API? Maybe it's obvious and it doesn't need documenting, but I (without access to Cycognito) couldn't find any info "online" :-)

@valentijnscholten valentijnscholten added this to the 2.48.0 milestone Jun 9, 2025
@manuel-sommer
Copy link
Contributor Author

Yeah, it is pretty obvious, but I just added a short sentence.

Copy link

DryRun Security

This pull request identifies a potential input validation issue in the dojo/tools/cycognito/parser.py file, where the affected_asset field is used to create an Endpoint object with minimal string replacements, which could potentially lead to unexpected behavior if the input is malformed or contains unexpected values.

⚠️ Potential Input Validation Issue in dojo/tools/cycognito/parser.py
Vulnerability Potential Input Validation Issue
Description The affected_asset field is directly used to create an Endpoint object with minimal string replacements. While not a critical vulnerability, this could potentially lead to unexpected behavior if the input contains malformed or unexpected values. The code should implement more robust input validation and sanitization before creating the Endpoint object.

import json
from datetime import datetime
from dojo.models import Endpoint, Finding
class CycognitoParser:
def get_scan_types(self):
return ["Cycognito Scan"]
def get_label_for_scan_types(self, scan_type):
return "Cycognito Scan"
def get_description_for_scan_types(self, scan_type):
return "Support Cycognito issues from returned JSON over API."
def get_findings(self, file, test):
data = json.load(file)
findings = []
for vulnerability in data:
description = ""
mitigation = ""
impact = ""
confidence = vulnerability.get("confidence", None)
affected_asset = vulnerability.get("affected_asset", None)
package = vulnerability.get("package", None)
exploitation_availability = vulnerability.get("exploitation_availability", None)
tools = vulnerability.get("tools", None)
continent = vulnerability.get("continent", None)
references = vulnerability.get("references", None)
tech_owners = vulnerability.get("tech_owners", None)
teams = vulnerability.get("teams", None)
potential_threat = vulnerability.get("potential_threat", None)
attacker_interest = vulnerability.get("attacker_interest", None)
tags = vulnerability.get("tags", None)
base_severity_score = vulnerability.get("base_severity_score", None)
vulnid = vulnerability.get("id", None)
remediation_method = vulnerability.get("remediation_method", None)
issue_id = vulnerability.get("issue_id", None)
first_detected = vulnerability.get("first_detected", None)
summary = vulnerability.get("summary", None)
exploitation_complexity = vulnerability.get("exploitation_complexity", None)
underground_activity = vulnerability.get("underground_activity", None)
resolved_at = vulnerability.get("resolved_at", None)
snooze_expiration = vulnerability.get("snooze_expiration", None)
attractiveness_label = vulnerability.get("attractiveness_label", None)
affected_ptr_domains = vulnerability.get("affected_ptr_domains", None)
affected_asset_tags = vulnerability.get("affected_asset_tags", None)
advisories = vulnerability.get("advisories", None)
environments = vulnerability.get("environments", None)
locations = vulnerability.get("locations", None)
region = vulnerability.get("region", None)
detection_complexity = vulnerability.get("detection_complexity", None)
port = vulnerability.get("port", None)
remediation_effort = vulnerability.get("remediation_effort", None)
exploitation_method = vulnerability.get("exploitation_method", None)
attractiveness = vulnerability.get("attractiveness", None)
title = vulnerability.get("title", None)
platforms = vulnerability.get("platforms", None)
exploitation_score = vulnerability.get("exploitation_score", None)
base_severity = vulnerability.get("base_severity", None)
issue_type = vulnerability.get("issue_type", None)
organizations = vulnerability.get("organizations", None)
business_units = vulnerability.get("business_units", None)
cve_ids = vulnerability.get("cve_ids", None)
comment = vulnerability.get("comment", None)
evidence = vulnerability.get("evidence", None)
remediation_steps = vulnerability.get("remediation_steps", None)
potential_impact = vulnerability.get("potential_impact", None)
if confidence is not None:
description += "**confidence:** " + str(confidence) + "\n"
if affected_asset is not None:
description += "**affected_asset:** " + str(affected_asset) + "\n"
if package is not None:
description += "**package:** " + str(package) + "\n"
if exploitation_availability is not None and not "None":
description += "**exploitation_availability:** " + str(exploitation_availability) + "\n"
if tools and tools is not None:
description += "**tools:** " + str(tools) + "\n"
if continent and continent is not None:
description += "**continent:** " + str(", ".join(continent)) + "\n"
if tech_owners and tech_owners is not None:
description += "**tech_owners:** " + str(tech_owners) + "\n"
if teams and teams is not None:
description += "**teams:** " + str(teams) + "\n"
if potential_threat and potential_threat is not None:
description += "**potential_threat:** " + str(potential_threat) + "\n"
if attacker_interest is not None and not "None":
description += "**attacker_interest:** " + str(attacker_interest) + "\n"
if tags and tags is not None:
description += "**tags:** " + str(tags) + "\n"
if base_severity_score is not None:
description += "**base_severity_score:** " + str(base_severity_score) + "\n"
if vulnid is not None:
description += "**id:** " + str(vulnid) + "\n"
if remediation_method is not None:
mitigation += "**remediation_method:** " + str(remediation_method) + "\n"
if issue_id is not None:
description += "**issue_id:** " + str(issue_id) + "\n"
if summary is not None:
description += "**summary:** " + str(summary) + "\n"
if exploitation_complexity is not None and exploitation_complexity != "unknown":
description += "**exploitation_complexity:** " + str(exploitation_complexity) + "\n"
if underground_activity is not None:
description += "**underground_activity:** " + str(underground_activity) + "\n"
if resolved_at is not None:
description += "**resolved_at:** " + str(resolved_at) + "\n"
if snooze_expiration is not None:
description += "**snooze_expiration:** " + str(snooze_expiration) + "\n"
if attractiveness_label is not None:
description += "**attractiveness_label:** " + str(attractiveness_label) + "\n"
if affected_ptr_domains and affected_ptr_domains is not None:
description += "**affected_ptr_domains:** " + str(", ".join(affected_ptr_domains)) + "\n"
if affected_asset_tags and affected_asset_tags is not None:
description += "**affected_asset_tags:** " + "" + "\n"
if advisories and advisories is not None:
description += "**advisories:** " + str(advisories) + "\n"
if environments and environments is not None:
description += "**environments:** " + str(", ".join(environments)) + "\n"
if locations and locations is not None:
description += "**locations:** " + str(", ".join(locations)) + "\n"
if region and region is not None:
description += "**region:** " + str(", ".join(region)) + "\n"
if detection_complexity is not None:
description += "**detection_complexity:** " + str(detection_complexity) + "\n"
if port is not None:
description += "**port:** " + str(port) + "\n"
if remediation_effort is not None:
mitigation += "**remediation_effort:** " + str(remediation_effort) + "\n"
if exploitation_method is not None and exploitation_method != "unknown":
description += "**exploitation_method:** " + str(exploitation_method) + "\n"
if attractiveness is not None:
description += "**attractiveness:** " + str(attractiveness) + "\n"
if platforms is not None:
description += "**platforms:** " + str(", ".join(platforms)) + "\n"
if exploitation_score is not None:
description += "**exploitation_score:** " + str(exploitation_score) + "\n"
if issue_type is not None:
description += "**issue_type:** " + str(issue_type) + "\n"
if organizations is not None:
description += "**organizations:** " + str(", ".join(organizations)) + "\n"
if business_units is not None:
description += "**business_units:** " + str(", ".join(business_units)) + "\n"
if comment is not None:
description += "**comment:** " + str(comment) + "\n"
if evidence is not None:
description += "**evidence:** " + str(evidence) + "\n"
if remediation_steps is not None:
mitigation += "**remediation_steps:** " + str("\n ".join(remediation_steps)) + "\n"
if potential_impact and potential_impact is not None:
impact = "**potential_impact:** " + str(", ".join(potential_impact)) + "\n"
finding = Finding(
title=title,
test=test,
description=description,
severity=base_severity.capitalize(),
references=str("\n".join(references)),
date=datetime.strptime(first_detected, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d"),
dynamic_finding=True,
mitigation=mitigation,
impact=impact,
)
if cve_ids and cve_ids is not None:
finding.unsaved_vulnerability_ids = []
for cve_id in cve_ids:
finding.unsaved_vulnerability_ids.append(cve_id)
finding.unsaved_endpoints = []
finding.unsaved_endpoints.append(Endpoint(host=affected_asset.replace("ip/", "").replace("webapp/", "").replace("cert/", "").replace("domain/", "")))
findings.append(finding)
return findings


All finding details can be found in the DryRun Security Dashboard.

@Maffooch Maffooch requested a review from hblankenship June 11, 2025 23:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs parser settings_changes Needs changes to settings.py based on changes in settings.dist.py included in this PR unittests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants