Skip to content

Conversation

@jy-tan
Copy link
Contributor

@jy-tan jy-tan commented Jan 31, 2026

Summary

Adds CSRF token normalization to the Django instrumentation to ensure consistent record/replay testing. Django CSRF tokens are dynamically generated, meaning they differ between recording and replay, causing comparison failures for any HTML form containing CSRF tokens.

Changes

  • Add new csrf_utils.py module with normalize_csrf_in_body() function that replaces CSRF tokens with a fixed placeholder (__DRIFT_CSRF__)
  • Update middleware.py to normalize CSRF tokens in two places:
    • During recording: normalize tokens in the span response body (before storage)
    • During replay: normalize tokens in the actual HTTP response (so the replayed response matches the recorded one)
  • Add e2e test coverage with a new /api/csrf-form endpoint that returns an HTML form with a CSRF token

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 5 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="drift/instrumentation/django/middleware.py">

<violation number="1" location="drift/instrumentation/django/middleware.py:282">
P2: Normalizing the response body without checking Content-Encoding can corrupt compressed HTML responses (e.g., gzip), since the body is decoded as UTF-8 regardless of encoding. Skip normalization unless the response is uncompressed/identity.</violation>

<violation number="2" location="drift/instrumentation/django/middleware.py:341">
P2: Span capture normalizes HTML bodies without checking Content-Encoding, which can corrupt compressed responses when decoding/re-encoding gzip/deflate payloads. Guard normalization to only run on uncompressed content.</violation>
</file>

<file name="drift/instrumentation/django/csrf_utils.py">

<violation number="1" location="drift/instrumentation/django/csrf_utils.py:37">
P2: Decoding with `errors="ignore"` can silently drop invalid bytes and mutate non‑UTF8 response bodies. Since you already catch decode errors, use strict decoding so non‑UTF8 bodies are returned unchanged.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@jy-tan jy-tan merged commit 3a7f613 into main Jan 31, 2026
22 checks passed
@jy-tan jy-tan deleted the handle-django-csrf branch January 31, 2026 03:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants