Skip to content

Conversation

valentijnscholten
Copy link
Member

@valentijnscholten valentijnscholten commented Sep 13, 2025

When filtering on dates, Python throws a WARNING in the logs. And in development/test environments this becomes an ERROR because we've stricter settings there to help us avoid these scenario's early in the dev cycle.

Traceback (most recent call last):
...
  File "/app/dojo/finding/views.py", line 370, in get
    return super().get(request, product_id=product_id, engagement_id=engagement_id)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/dojo/finding/views.py", line 351, in get
    paged_findings = get_page_items(request, filtered_findings.qs, 25)
                                             ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django_filters/filterset.py", line 250, in qs
    qs = self.filter_queryset(qs)
         ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django_filters/filterset.py", line 233, in filter_queryset
    queryset = self.filters[name].filter(queryset, value)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/dojo/filters.py", line 691, in filter
    return self.options[value][1](qs, self.field_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/dojo/filters.py", line 656, in <lambda>
    2: (_("Past 7 days"), lambda qs, name: qs.filter(**{
                                           
  File "/usr/local/lib/python3.11/site-packages/django/db/models/query.py", line 1476, in filter
    return self._filter_or_exclude(False, args, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/tagulous/models/tagged.py", line 142, in _filter_or_exclude
    qs = super(TaggedQuerySet, self)._filter_or_exclude(
         
  ....

Exception Type: RuntimeWarning at /finding/open
Exception Value: DateTimeField Finding.last_status_update received a naive datetime (2025-09-06 00:00:00) while time zone support is active.

This PR first introduced an integration tests to ensure the URL is crawled during testing. This resulted in the above ERROR, so the test works:

integration-tests-1  | ======================================================================
integration-tests-1  | FAIL: test_date_filter (__main__.VariousPagesTest.test_date_filter)
integration-tests-1  | ----------------------------------------------------------------------
integration-tests-1  | Traceback (most recent call last):
integration-tests-1  |   File "/app/tests/base_test_class.py", line 440, in tearDown
integration-tests-1  |     self.assertNoConsoleErrors()
integration-tests-1  |   File "/app/tests/base_test_class.py", line 435, in assertNoConsoleErrors
integration-tests-1  |     self.assertNotEqual(entry["level"], "SEVERE")
integration-tests-1  | AssertionError: 'SEVERE' == 'SEVERE'
integration-tests-1  | 
integration-tests-1  | ----------------------------------------------------------------------
integration-tests-1  | Ran 8 tests in 3.411s
integration-tests-1  | 
integration-tests-1  | FAILED (failures=1)
integration-tests-1  | Error: tests/check_various_pages.py test failed

The PR is now extended with fixes in all places I could find that were still using "naive" datetimes without timezone info.

@valentijnscholten valentijnscholten added this to the 2.50.3 milestone Sep 13, 2025
@valentijnscholten valentijnscholten changed the title test filter on last_status_update Fix naive datetime warnings/errors Sep 13, 2025
@valentijnscholten valentijnscholten marked this pull request as ready for review September 13, 2025 18:13
Copy link

DryRun Security

This pull request includes changes in dojo/tools/cyberwatch_galeax/parser.py where parse_detected_at, parse_fixed_at, and parse_datetime silently default to timezone.now() when input dates are missing or unparseable. This behavior can produce inaccurate detection/fix timestamps, skew remediation metrics, and compromise auditability and reporting by masking parsing errors from external sources.

Inaccurate Timestamps on Parsing Failure in dojo/tools/cyberwatch_galeax/parser.py
Vulnerability Inaccurate Timestamps on Parsing Failure
Description The parse_detected_at function in dojo/tools/cyberwatch_galeax/parser.py falls back to timezone.now() if parsing of the detected_at_str fails due to ValueError or TypeError. This means that if an external source provides a detected_at timestamp in an unexpected or malformed format, the system will record the current time as the detection time, rather than failing or indicating a parsing error. This can lead to inaccurate security metrics, audit trails, and SLA tracking, potentially masking the true age of vulnerabilities or misrepresenting their detection timeline.

)
unsaved_endpoint_status.append(endpoint_status)
mitigated_date = (max(mitigated_dates) if mitigated_dates else timezone.now()) if not active_status else None
return unsaved_endpoints, unsaved_endpoint_status, active_status, mitigated_date
def parse_detected_at(self, detected_at_str):
"""Parse the detected_at field for a security issue server."""
try:
return datetime.strptime(detected_at_str, "%Y-%m-%dT%H:%M:%S.%fZ")
except (ValueError, TypeError):
return timezone.now()
def parse_fixed_at(self, fixed_at_str):
"""Parse fixed_at datetime, defaulting to now if parsing fails."""

Inaccurate Timestamps on Parsing Failure in dojo/tools/cyberwatch_galeax/parser.py
Vulnerability Inaccurate Timestamps on Parsing Failure
Description The parse_fixed_at function in dojo/tools/cyberwatch_galeax/parser.py defaults to returning timezone.now() when the input fixed_at_str is None or cannot be parsed. This behavior can lead to inaccurate mitigation records, as a malformed or missing fixed_at date from an external system will cause the vulnerability to be recorded as fixed at the time of data import, rather than its actual remediation time. This skews remediation metrics, compromises audit trail integrity, and can affect SLA compliance.

return datetime.strptime(fixed_at_str, "%Y-%m-%dT%H:%M:%S.%f%z")
except ValueError as e:
logger.error(f'Error parsing fixed_at date "{fixed_at_str}": {e}')
return timezone.now()
def parse_datetime(self, dt_str):
"""Parse a datetime string with fallback to now on error."""

Inaccurate Timestamps on Parsing Failure in dojo/tools/cyberwatch_galeax/parser.py
Vulnerability Inaccurate Timestamps on Parsing Failure
Description The parse_datetime function in the Cyberwatch Galeax parser silently replaces any unparseable datetime string with the current timestamp (timezone.now()). This leads to data integrity issues where security-critical event timelines (e.g., detection or mitigation dates from external reports) are misrepresented. This can severely impact auditability, reporting accuracy, and decision-making within the security platform.

return datetime.strptime(dt_str, "%Y-%m-%dT%H:%M:%S.%f%z")
except (ValueError, TypeError):
logger.error(f'Error parsing datetime "{dt_str}"')
return timezone.now()
def parse_cvss(self, cvss_v3_vector, json_data):
if cvss_v3_vector:


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

@mtesauro
Copy link
Contributor

I cannot tell you how much I WILL NOT miss seeing these in the logs...

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants