Add Simple Metrics API endpoint#12533
Conversation
🔴 Risk threshold exceeded.This pull request introduces several security concerns, including potential information disclosure through error messages and metrics endpoints, user enumeration via logout logging, and a possible denial of service vulnerability in the metrics view. The changes affect multiple files in the dojo directory and require careful review to mitigate potential security risks.
|
| Vulnerability | Configured Codepaths Edit |
|---|---|
| Description | Sensitive edits detected for this file. Sensitive file paths and allowed authors can be configured in .dryrunsecurity.yaml. |
⚠️ Configured Codepaths Edit in dojo/utils.py
| Vulnerability | Configured Codepaths Edit |
|---|---|
| Description | Sensitive edits detected for this file. Sensitive file paths and allowed authors can be configured in .dryrunsecurity.yaml. |
⚠️ Configured Codepaths Edit in dojo/api_v2/serializers.py
| Vulnerability | Configured Codepaths Edit |
|---|---|
| Description | Sensitive edits detected for this file. Sensitive file paths and allowed authors can be configured in .dryrunsecurity.yaml. |
⚠️ Configured Codepaths Edit in dojo/api_v2/views.py
| Vulnerability | Configured Codepaths Edit |
|---|---|
| Description | Sensitive edits detected for this file. Sensitive file paths and allowed authors can be configured in .dryrunsecurity.yaml. |
⚠️ Information Disclosure via Error Messages in docs/content/en/api/metrics-endpoint.md
| Vulnerability | Information Disclosure via Error Messages |
|---|---|
| Description | The documentation provides detailed error messages that could help an attacker understand backend validation logic. While informative for developers, these specific error messages reveal implementation details that could aid in probing the API's input validation mechanisms. |
django-DefectDojo/docs/content/en/api/metrics-endpoint.md
Lines 1 to 169 in 1737ad2
⚠️ User Enumeration via Logout Logging in dojo/utils.py
| Vulnerability | User Enumeration via Logout Logging |
|---|---|
| Description | The logout logging differentiates between authenticated and anonymous users, which could potentially provide a side channel for user enumeration if log entries are accessible or observable. |
django-DefectDojo/dojo/utils.py
Lines 2387 to 2396 in 1737ad2
⚠️ Information Disclosure via New API Endpoint in dojo/urls.py
| Vulnerability | Information Disclosure via New API Endpoint |
|---|---|
| Description | The new metrics endpoint could expose sensitive system information if not properly secured. The introduction of this endpoint requires careful review to ensure it does not leak operational details. |
django-DefectDojo/dojo/urls.py
Lines 58 to 64 in 1737ad2
⚠️ Information Disclosure via Metrics in dojo/api_v2/serializers.py
| Vulnerability | Information Disclosure via Metrics |
|---|---|
| Description | The serializer exposes detailed metrics about product types, including vulnerability counts by severity. If not properly protected, this could provide an attacker insights into the organization's security posture and vulnerability landscape. |
django-DefectDojo/dojo/api_v2/serializers.py
Lines 3089 to 3107 in 1737ad2
⚠️ Potential Denial of Service in dojo/api_v2/views.py
| Vulnerability | Potential Denial of Service |
|---|---|
| Description | The SimpleMetricsViewSet sets pagination_class = None, which could allow resource exhaustion if a large number of product types or findings are processed. This could lead to excessive server resource consumption. |
django-DefectDojo/dojo/api_v2/views.py
Lines 11 to 17 in 1737ad2
⚠️ Information Disclosure via Error Messaging in dojo/api_v2/views.py
| Vulnerability | Information Disclosure via Error Messaging |
|---|---|
| Description | The error message for product_type_id does not clearly distinguish between a non-existent product type and an unauthorized product type. This could potentially allow for subtle user enumeration. |
django-DefectDojo/dojo/api_v2/views.py
Lines 11 to 17 in 1737ad2
We've notified @mtesauro.
All finding details can be found in the DryRun Security Dashboard.
| S0 = serializers.IntegerField(read_only=True) # Critical | ||
| S1 = serializers.IntegerField(read_only=True) # High | ||
| S2 = serializers.IntegerField(read_only=True) # Medium | ||
| S3 = serializers.IntegerField(read_only=True) # Low | ||
| S4 = serializers.IntegerField(read_only=True) # Info |
There was a problem hiding this comment.
Why not just name these after the severity level rather than commenting and documenting the conversion for Sx -> severity level?
There was a problem hiding this comment.
The S0-S4 naming is maintained for potential backward compatibility and codebase consistency. The Sx pattern is used consistently throughout the UI's templates and database queries. That said I am happy to make the change to named labels to make it more clear for anyone integrating.
There was a problem hiding this comment.
FWIW, the S0-4 naming is the absolute definition of legacy code. That was initially used in the very, very early versions of DefectDojo then transitions to the more typical "Critical, High, ..."
So, even though the code has S# all over it, the 'modern' version of that is the more human friendly labels.
There was a problem hiding this comment.
I changed the API to return the human readable labels, also as part of refactoring the view to be able to share the same code between UI and API, I updated the Django templates to use the human readable labels as well.
curl -H "Authorization: Token REDACTED" \
-H "Content-Type: application/json" \
http://localhost:8080/api/v2/metrics/simple/
[
{
"product_type_id": 2,
"product_type_name": "Production",
"Total": 0,
"critical": 0,
"high": 0,
"medium": 0,
"low": 0,
"info": 0,
"Opened": 0,
"Closed": 0
},
{
"product_type_id": 1,
"product_type_name": "Research and Development",
"Total": 0,
"critical": 0,
"high": 0,
"medium": 0,
"low": 0,
"info": 0,
"Opened": 0,
"Closed": 0
}
]
valentijnscholten
left a comment
There was a problem hiding this comment.
The (almost the) same simple metrics queries are also in dojo/metrics/views.py. Could you look at having them in once place?
1737ad2 to
61e7ea1
Compare
🔴 Risk threshold exceeded.This pull request introduces several security considerations, including potential information disclosure through metrics serialization, IP logging during logout, and product type enumeration, with multiple sensitive files being edited across the project's API, utility, and template components. While none of the findings are blocking, they highlight areas where careful access control and error message handling could mitigate potential reconnaissance or information leakage risks.
🔴 Configured Codepaths Edit in
|
| Vulnerability | Configured Codepaths Edit |
|---|---|
| Description | Sensitive edits detected for this file. Sensitive file paths and allowed authors can be configured in .dryrunsecurity.yaml. |
🔴 Configured Codepaths Edit in dojo/urls.py
| Vulnerability | Configured Codepaths Edit |
|---|---|
| Description | Sensitive edits detected for this file. Sensitive file paths and allowed authors can be configured in .dryrunsecurity.yaml. |
🔴 Configured Codepaths Edit in dojo/utils.py
| Vulnerability | Configured Codepaths Edit |
|---|---|
| Description | Sensitive edits detected for this file. Sensitive file paths and allowed authors can be configured in .dryrunsecurity.yaml. |
🔴 Configured Codepaths Edit in dojo/api_v2/serializers.py
| Vulnerability | Configured Codepaths Edit |
|---|---|
| Description | Sensitive edits detected for this file. Sensitive file paths and allowed authors can be configured in .dryrunsecurity.yaml. |
🔴 Configured Codepaths Edit in dojo/api_v2/views.py
| Vulnerability | Configured Codepaths Edit |
|---|---|
| Description | Sensitive edits detected for this file. Sensitive file paths and allowed authors can be configured in .dryrunsecurity.yaml. |
🔴 Configured Codepaths Edit in dojo/metrics/views.py
| Vulnerability | Configured Codepaths Edit |
|---|---|
| Description | Sensitive edits detected for this file. Sensitive file paths and allowed authors can be configured in .dryrunsecurity.yaml. |
🔴 Configured Codepaths Edit in dojo/templates/dojo/pt_counts.html
| Vulnerability | Configured Codepaths Edit |
|---|---|
| Description | Sensitive edits detected for this file. Sensitive file paths and allowed authors can be configured in .dryrunsecurity.yaml. |
Metrics Information Disclosure in dojo/api_v2/serializers.py
| Vulnerability | Metrics Information Disclosure |
|---|---|
| Description | The new SimpleMetricsSerializer exposes detailed security metrics, including finding counts by severity and status. If not properly secured, this could provide attackers with insights into the application's security posture and internal metrics. |
django-DefectDojo/dojo/api_v2/serializers.py
Lines 3103 to 3124 in 405b676
Logout IP Logging in dojo/utils.py
| Vulnerability | Logout IP Logging |
|---|---|
| Description | The patch introduces logging of IP addresses for both authenticated and anonymous logout attempts. While logging can be useful for auditing, logging IP addresses for anonymous users could potentially be used for tracking or reconnaissance if not carefully managed. |
django-DefectDojo/dojo/utils.py
Lines 2397 to 2406 in 405b676
Product Type Enumeration in dojo/api_v2/views.py
| Vulnerability | Product Type Enumeration |
|---|---|
| Description | The new metrics API endpoint allows filtering by product type ID, which could potentially enable an attacker to enumerate valid product type IDs through careful probing of the API responses. While the implementation includes authorization checks, the distinct error messages and response handling could leak information about the existence of product types. |
django-DefectDojo/dojo/api_v2/views.py
Lines 3174 to 3296 in 405b676
Test Credential Linting Disabled in ruff.toml
| Vulnerability | Test Credential Linting Disabled |
|---|---|
| Description | Disabling the S106 linting rule for test files removes warnings about hardcoded passwords, which could lead to accidental exposure of credentials if test files are mishandled or the repository is compromised. |
Lines 112 to 118 in 405b676
Verbose Error Message Disclosure in docs/content/en/api/metrics-endpoint.md
| Vulnerability | Verbose Error Message Disclosure |
|---|---|
| Description | The API documentation reveals detailed error messages that provide insights into the backend's validation logic. While informative for developers, these messages could assist an attacker in understanding the application's input validation mechanisms and potential attack surfaces. |
django-DefectDojo/docs/content/en/api/metrics-endpoint.md
Lines 1 to 169 in 405b676
We've notified @mtesauro.
All finding details can be found in the DryRun Security Dashboard.
61e7ea1 to
f10e455
Compare
| with connection.cursor() as cursor: | ||
| cursor.execute(""" | ||
| INSERT INTO dojo_finding ( | ||
| title, description, severity, test_id, reporter_id, date, | ||
| active, verified, false_p, duplicate, out_of_scope, | ||
| created, last_reviewed, last_status_update, | ||
| mitigated, is_mitigated, risk_accepted, under_review, | ||
| under_defect_review, review_requested_by_id, | ||
| defect_review_requested_by_id, sonarqube_issue_id, | ||
| hash_code, line, file_path, component_name, component_version, | ||
| static_finding, dynamic_finding, created_from_issue_id, | ||
| status_id, group_id, sast_source_object, sast_sink_object, | ||
| sast_source_line, sast_source_file_path, nb_occurences, | ||
| publish_date, service, planned_remediation_date, | ||
| planned_remediation_version, effort_for_fixing, | ||
| impact, steps_to_reproduce, severity_justification, | ||
| references, mitigation, references_raw, mitigation_raw, | ||
| cvssv3, cvssv3_score, url, tags, scanner_confidence, | ||
| numerical_severity, param, payload, cwe, unique_id_from_tool, | ||
| vuln_id_from_tool, sast_source_function, sast_source_function_start, | ||
| sast_source_function_end, sast_sink_function, sast_sink_line, | ||
| sast_sink_file_path, sast_sink_function_start, | ||
| sast_sink_function_end, epss_score, epss_percentile, | ||
| cve_id, has_tags, sonarqube_project_key, | ||
| sonarqube_project_branch, sonarqube_project_pull_request | ||
| ) VALUES ( | ||
| %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, | ||
| NOW(), NULL, NOW(), NULL, %s, %s, %s, %s, NULL, NULL, NULL, | ||
| '', NULL, '', '', '', %s, %s, NULL, NULL, NULL, '', | ||
| '', NULL, '', 1, NOW(), '', NULL, '', '', '', '', '', | ||
| '', '', '', '', '', NULL, '', '', | ||
| CASE %s | ||
| WHEN 'Critical' THEN 0 | ||
| WHEN 'High' THEN 1 | ||
| WHEN 'Medium' THEN 2 | ||
| WHEN 'Low' THEN 3 | ||
| ELSE 4 | ||
| END, | ||
| '', '', NULL, '', '', '', NULL, NULL, '', NULL, '', | ||
| NULL, NULL, NULL, NULL, NULL, %s, '', '', '' | ||
| ) | ||
| """, [ |
There was a problem hiding this comment.
Could you elaborate on why inserting the finding this way is needed?
There was a problem hiding this comment.
I did this to bypass Django signals/Celery to ensure the test data was predictable/deterministic for testing the API call.
There was a problem hiding this comment.
But why is that needed? I can't think of reason why a test would fail unless a finding is inserted via raw SQL. It also looks like this method is never called, or am I misreading the PR?
There was a problem hiding this comment.
Thank you for digging into that. You are absolutely correct, it is unused. I suspect I was using this for initial testing before I discovered the test data fixture. I'll spend some time refactoring the unit tests here to make sure they align with the structure for the rest of the project.
| "hash_code": "c89d25e445b088ba339908f68e15e3177b78d22f3039d1bfea51c4be251bf4e0", | ||
| "last_reviewed": null | ||
| } | ||
| },{ |
There was a problem hiding this comment.
Removing the duplicate PK:8 as it was causing my unit tests to fail randomly
f10e455 to
405b676
Compare
|
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
Description
This PR adds a REST API endpoint
/api/v2/metrics/simplefor programmatic access to DefectDojo's simple metrics functionality. This will enable automated reporting and external dashboard integrationChanges:
/metrics/simpleendpointdojo/utils.pythat caused crashes when anonymous users triggered logout events by handling null user casesTest results
uwsgi-1 | ----------------------------------------------------------------------
uwsgi-1 | Ran 43 tests in 4.588s
uwsgi-1 |
uwsgi-1 | OK (skipped=32)
Documentation
Checklist
dev.dev.bugfixbranch.Response