Skip to content

rerecord

9dcf565
Select commit
Loading
Failed to load commit list.
Merged

Finding Groups: Respect minimum severity and active/verified rules when pushing to JIRA #12475

rerecord
9dcf565
Select commit
Loading
Failed to load commit list.
DryRunSecurity / General Security Analyzer succeeded Jun 22, 2025 in 2s

DryRun Security

Details

General Security Analyzer Findings: 5 detected

⚠️ Hardcoded Authentication Token unittests/vcr/jira/JIRAImportAndPushTestApi.test_import_no_push_to_jira.yaml (click for details)
Type Hardcoded Authentication Token
Description Test files contain hardcoded authentication tokens (e.g., 'Token xxx'), which represents a security anti-pattern. Even as a placeholder, this indicates potential mishandling of sensitive credentials. Best practices recommend using environment variables, secure configuration management, or dedicated secrets management systems to handle authentication tokens.
Filename unittests/vcr/jira/JIRAImportAndPushTestApi.test_import_no_push_to_jira.yaml
CodeLink
- request:
body: '{"description": "Event test_added has occurred.", "title": "Test created
for Security How-to: 1st Quarter Engagement: ZAP Scan", "user": null, "url_ui":
"http://localhost:8080/test/105", "url_api": "http://localhost:8080/api/v2/tests/105/",
"product_type": {"name": "ebooks", "id": 2, "url_ui": "http://localhost:8080/product/type/2",
"url_api": "http://localhost:8080/api/v2/product_types/2/"}, "product": {"name":
"Security How-to", "id": 2, "url_ui": "http://localhost:8080/product/2", "url_api":
"http://localhost:8080/api/v2/products/2/"}, "engagement": {"name": "1st Quarter
Engagement", "id": 1, "url_ui": "http://localhost:8080/engagement/1", "url_api":
"http://localhost:8080/api/v2/engagements/1/"}, "test": {"title": null, "id":
105, "url_ui": "http://localhost:8080/test/105", "url_api": "http://localhost:8080/api/v2/tests/105/"}}'
headers:
Accept:
- application/json
⚠️ Unencrypted API Communication unittests/vcr/jira/JIRAImportAndPushTestApi.test_import_no_push_to_jira.yaml (click for details)
Type Unencrypted API Communication
Description Test recordings show API communication over unencrypted HTTP (http://localhost:8080, http://webhook.endpoint:8080). While this is in test data, it highlights a critical security risk if replicated in production. All sensitive API communications must use HTTPS to prevent eavesdropping and man-in-the-middle attacks.
Filename unittests/vcr/jira/JIRAImportAndPushTestApi.test_import_no_push_to_jira.yaml
CodeLink
- request:
body: '{"description": "Event test_added has occurred.", "title": "Test created
for Security How-to: 1st Quarter Engagement: ZAP Scan", "user": null, "url_ui":
"http://localhost:8080/test/105", "url_api": "http://localhost:8080/api/v2/tests/105/",
"product_type": {"name": "ebooks", "id": 2, "url_ui": "http://localhost:8080/product/type/2",
"url_api": "http://localhost:8080/api/v2/product_types/2/"}, "product": {"name":
"Security How-to", "id": 2, "url_ui": "http://localhost:8080/product/2", "url_api":
"http://localhost:8080/api/v2/products/2/"}, "engagement": {"name": "1st Quarter
Engagement", "id": 1, "url_ui": "http://localhost:8080/engagement/1", "url_api":
"http://localhost:8080/api/v2/engagements/1/"}, "test": {"title": null, "id":
105, "url_ui": "http://localhost:8080/test/105", "url_api": "http://localhost:8080/api/v2/tests/105/"}}'
headers:
Accept:
- application/json
⚠️ Information Disclosure via Debug Logging dojo/jira_link/helper.py (click for details)
Type Information Disclosure via Debug Logging
Description New debug logging statements in jira_link/helper.py expose internal object details like finding IDs, active status, and verification flags. If debug logs are enabled in production, this could reveal sensitive system internals and finding states.
Filename dojo/jira_link/helper.py
CodeLink
return None
def _safely_get_obj_status_for_jira(obj: Finding | Finding_Group, *, isenforced: bool = False) -> str:
# Accommodating a strange behavior where a obj sometimes prefers `obj.status` rather than `obj.status()`
status = []
if isinstance(obj, Finding):
try:
return obj.status()
except TypeError: # TypeError: 'str' object is not callable
return obj.status
if isinstance(obj, Finding_Group):
# only consider findings that are above the minimum threshold, but includ inactive and non-verified findings
findings = get_finding_group_findings_above_threshold(obj)
if not findings:
return ["Empty", "Inactive"]
for find in findings:
logger.debug(f"Finding {find.id} status {find.active} {find.verified} {find.is_mitigated}")
# This iterates 3 times over the list of findings, but any code doing 1 iteration would looke it's from 1990
if any(find.active for find in findings):
status += ["Active"]
if any((find.active and find.verified) for find in findings):
status += ["Verified"]
if all(find.is_mitigated for find in findings):
status += ["Mitigated", "Inactive"]
# if no active findings are found, we must assume the status is inactive
return status or ["Inactive"]
# checks if a finding can be pushed to JIRA
⚠️ Business Logic Flaw in Finding Group Status Determination dojo/jira_link/helper.py (click for details)
Type Business Logic Flaw in Finding Group Status Determination
Description The new _safely_get_obj_status_for_jira function introduces complex logic for determining Finding Group statuses. Subtle flaws in this logic could lead to incorrect authorization decisions, potentially allowing unqualified findings to be pushed to JIRA or preventing legitimate findings from being processed.
Filename dojo/jira_link/helper.py
CodeLink
logger.debug("can_be_pushed_to_jira: %s, %s, %s", active, verified, severity)
if not active or (not verified and isenforced):
logger.debug("Findings must be active and verified, if enforced by system settings, to be pushed to JIRA")
return False, "Findings must be active and verified, if enforced by system settings, to be pushed to JIRA", "error_not_active_or_verified"
if jira_minimum_threshold and jira_minimum_threshold > Finding.get_number_severity(severity):
logger.debug(f"Finding below the minimum JIRA severity threshold ({System_Settings.objects.get().jira_minimum_severity}).")
return False, f"Finding below the minimum JIRA severity threshold ({System_Settings.objects.get().jira_minimum_severity}).", "error_below_minimum_threshold"
elif isinstance(obj, Finding_Group):
finding_group_status = _safely_get_obj_status_for_jira(obj)
logger.error(f"Finding group status: {finding_group_status}")
if "Empty" in finding_group_status:
return False, f"{to_str_typed(obj)} cannot be pushed to jira as it contains no findings above minimum treshold.", "error_empty"
if isenforced and "Verified" not in finding_group_status:
return False, f"{to_str_typed(obj)} cannot be pushed to jira as it contains no active and verified findings above minimum treshold.", "error_not_active_or_verified"
if "Active" not in _safely_get_obj_status_for_jira(obj):
return False, f"{to_str_typed(obj)} cannot be pushed to jira as it contains no active findings above minimum treshold.", "error_inactive"
else:
return False, f"{to_str_typed(obj)} cannot be pushed to jira as it is of unsupported type.", "error_unsupported"
⚠️ Potential Denial of Service via Resource Exhaustion dojo/jira_link/helper.py (click for details)
Type Potential Denial of Service via Resource Exhaustion
Description Functions like jira_priority and get_sla_deadline for Finding Groups iterate over findings, potentially becoming computationally expensive with large finding groups. An attacker could exploit this by creating extremely large finding groups, leading to performance degradation.
Filename dojo/jira_link/helper.py
CodeLink
def jira_priority(obj):
if isinstance(obj, Finding):
return get_jira_instance(obj).get_priority(obj.severity)
if isinstance(obj, Finding_Group):
# priority based on qualified findings, so if alls criticals get closed, the priority will gets lowered etc
active_findings = get_qualified_findings(obj)
if not active_findings:
# using a string literal "Info" as we don't really have a "enum" for this anywhere
max_number_severity = Finding.get_number_severity("Info")
else:
max_number_severity = max(Finding.get_number_severity(find.severity) for find in active_findings)
return get_jira_instance(obj).get_priority(Finding.get_severity(max_number_severity))
msg = f"Unsupported object type for jira_priority: {obj.__class__.__name__}"
raise ValueError(msg)
def jira_environment(obj):