-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Auditlog: Add django-pghistory as audit log (optional for now)
#13126
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
ruff
d89dd5e
Auditlog: Add django-pghistory as audit log (optional for now)
#13126
d89dd5e
DryRun Security
Details
General Security Analyzer Findings: 8 detected
⚠️ IP Address Spoofing in Audit Logs dojo/middleware.py (click for details)
| Type | IP Address Spoofing in Audit Logs | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description | The PgHistoryMiddleware in dojo/middleware.py directly uses the HTTP_X_FORWARDED_FOR header to determine the client's IP address for audit logging. This header is easily spoofable by an attacker. The code explicitly takes the first IP address from the comma-separated list in HTTP_X_FORWARDED_FOR. Without proper configuration of USE_X_FORWARDED_HOST and FORWARED_HOST_ALLOWED_IPS in Django settings, or a trusted proxy that sanitizes this header, an attacker can set this header to an arbitrary IP address, thereby falsifying their origin in the audit logs. This undermines the integrity and reliability of the audit trail, as audit logs could be manipulated to obscure an attacker's true source IP. |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| Filename | dojo/middleware.py | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| CodeLink | django-DefectDojo/dojo/middleware.py Lines 192 to 217 in 5433949
|
⚠️ Denial-of-Service via inefficient icontains lookup on pghistory_context dojo/filters.py (click for details)
| Type | Denial-of-Service via inefficient icontains lookup on pghistory_context | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description | The PgHistoryFilter in dojo/filters.py uses icontains lookups for remote_addr and pgh_diff. The icontains lookup in Django translates to a LIKE '%value%' SQL query in PostgreSQL.PostgreSQL's standard B-tree indexes, even expression indexes created on (metadata->>'remote_addr') as seen in dojo/db_migrations/0244_pghistory_indices.py, are not effectively utilized for LIKE '%value%' queries. B-tree indexes are optimized for prefix matches (LIKE 'value%') or exact matches, but not for arbitrary substring searches.Similarly, the GIN index created on the entire metadata JSONB field (ON "pghistory_context" USING GIN ("metadata")) is primarily designed for JSONB-specific operators (e.g., @>, ?, `? |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Filename | dojo/filters.py | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CodeLink | django-DefectDojo/dojo/filters.py Lines 3488 to 3554 in 5433949
|
⚠️ Information Disclosure: User Enumeration via Audit Log Fallback Logic dojo/engagement/signals.py (click for details)
| Type | Information Disclosure: User Enumeration via Audit Log Fallback Logic | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description | The action_history view, accessible to users with Product_View or Engagement_View permissions, displays audit events. When an object (like an Engagement, Product, or Finding Group) is deleted, the system attempts to identify the deleting user from pghistory or django-auditlog. If a user is found, their username is explicitly included in the audit description displayed in the action_history view. This allows low-privileged users to enumerate the usernames of users (including potentially higher-privileged ones) who performed deletion actions on objects they have view access to. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Filename | dojo/engagement/signals.py | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CodeLink | django-DefectDojo/dojo/engagement/signals.py Lines 47 to 84 in 5433949
|
⚠️ Destructive Operation with --force option bypasses critical confirmation dojo/management/commands/pghistory_clear.py (click for details)
| Type | Destructive Operation with --force option bypasses critical confirmation | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description | The pghistory_clear.py management command includes a --force flag that, when used, bypasses the interactive confirmation prompt before executing a destructive operation (truncating or dropping pghistory audit log tables). This means that an attacker who has gained the ability to execute Django management commands could use this flag to silently and irreversibly delete audit log data, potentially covering their tracks without user interaction. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Filename | dojo/management/commands/pghistory_clear.py | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CodeLink | django-DefectDojo/dojo/management/commands/pghistory_clear.py Lines 1 to 206 in 5433949
|
⚠️ Potential for Information Disclosure of Sensitive Data via Audit Logs dojo/management/commands/pghistory_backfill.py (click for details)
| Type | Potential for Information Disclosure of Sensitive Data via Audit Logs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description | The pghistory_backfill.py command uses a manually maintained, hardcoded dictionary excluded_fields_map to prevent sensitive fields from being written into the audit history during a backfill. While the currently identified sensitive fields (password, header_name, header_value) are correctly excluded in both the backfill script and the live django-pghistory configuration, this manual approach is fragile. If a new sensitive field is added to a model in the future, a developer might forget to update this exclusion list in pghistory_backfill.py (and potentially dojo/auditlog.py), leading to sensitive data being inadvertently written to the audit log tables. These logs may have different access controls and longer retention periods, increasing the risk of information disclosure. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Filename | dojo/management/commands/pghistory_backfill.py | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CodeLink | django-DefectDojo/dojo/management/commands/pghistory_backfill.py Lines 1 to 265 in 5433949
|
⚠️ Incomplete Error Handling for Audit Trigger Failures dojo/auditlog.py (click for details)
| Type | Incomplete Error Handling for Audit Trigger Failures | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description | The enable_django_pghistory, disable_django_pghistory, and configure_pghistory_triggers functions in dojo/auditlog.py use broad try...except Exception blocks when calling pgtrigger commands. If pgtrigger fails to enable or disable its database triggers (e.g., due to database connection issues, permissions, or misconfiguration), the application will log a warning but continue to start and operate. This leads to a silent failure of the django-pghistory audit logging system, resulting in a critical loss of security visibility as audit events will not be recorded, despite the system appearing to function normally. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Filename | dojo/auditlog.py | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CodeLink | django-DefectDojo/dojo/auditlog.py Lines 1 to 388 in 5433949
|
⚠️ Application Starts with Incomplete Database Schema docker/entrypoint-initializer.sh (click for details)
| Type | Application Starts with Incomplete Database Schema | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Description | The entrypoint-initializer.sh script has been modified to allow the application to continue starting even if Django database migrations are detected as missing. This change transforms a critical failure condition into a warning. Running an application with an inconsistent database schema can lead to unpredictable behavior, data integrity issues, and potential security vulnerabilities if critical security-related model changes (e.g., new access control fields, data validation constraints) are not applied to the database. While the change aims to improve resilience, it introduces a risk of operating in an undefined state where security controls might not be fully enforced. |
||||||||||||||||||||||||||||||||||||||||||||||||||
| Filename | docker/entrypoint-initializer.sh | ||||||||||||||||||||||||||||||||||||||||||||||||||
| CodeLink | django-DefectDojo/docker/entrypoint-initializer.sh Lines 121 to 145 in 5433949
|
⚠️ Information Disclosure via Raw Audit Data dojo/templates/dojo/action_history.html (click for details)
| Type | Information Disclosure via Raw Audit Data | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description | The action_history.html template directly renders raw pgh_data and pgh_context fields from django-pghistory events. The pgh_data field contains a snapshot of all model fields (unless explicitly excluded), and pgh_context contains request details like remote_addr and url. This can lead to the unintended exposure of sensitive information (e.g., internal notes, PII like IP addresses, or sensitive GET parameters in URLs) to authorized users who access the audit history, even if they don't have direct access to those specific sensitive fields in the live object. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Filename | dojo/templates/dojo/action_history.html | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CodeLink | django-DefectDojo/dojo/templates/dojo/action_history.html Lines 4 to 158 in 5433949
|