Skip to content

fix(gitlab): sanitize ANSI escape sequences from MR webhook author email/name#120024

Closed
billyvg wants to merge 1 commit into
masterfrom
claude/hopeful-rubin-dtmg3b
Closed

fix(gitlab): sanitize ANSI escape sequences from MR webhook author email/name#120024
billyvg wants to merge 1 commit into
masterfrom
claude/hopeful-rubin-dtmg3b

Conversation

@billyvg

@billyvg billyvg commented Jul 19, 2026

Copy link
Copy Markdown
Member

Summary

Fixes a production DataError: value too long for type character varying(200) crash in the GitLab webhook handler.

Root Cause

A GitLab MR webhook arrived with ANSI terminal escape sequences appended to the commit author email field in the last_commit.author.email payload key — e.g. user@example.com followed by 34 cursor-left (\x1b[d) and 33 cursor-right (\x1b[c) sequences, totalling ~170 extra bytes and pushing the value well past 200 characters.

MergeEventWebhook.__call__ extracted this value verbatim and passed it directly to CommitAuthor.objects.get_or_create(email=<malformed_value>, ...). PostgreSQL's varchar(200) constraint on the sentry_commitauthor.email column rejected the insert with StringDataRightTruncation, which Django surfaced as DataError. The entire webhook request failed with a 500.

What was ruled out

  • Widening the DB column: wrong direction — the column is already generous at 200 chars; accommodating injected garbage is not the answer.
  • Catching DataError silently: hides the bug, allows future similar injections to fail undetected, and does not store the author at all so the PR record ends up without an author.
  • Truncating blindly without stripping: ANSI sequences like \x1b[d consist of a non-printable ESC byte (\x1b) followed by printable ASCII characters ([d). Stripping only non-printable bytes would leave [d[d[d… in the stored email, which is still wrong data.

Fix

Add _sanitize_author_field() in src/sentry/integrations/gitlab/webhooks.py and apply it when extracting author email and name from MR and push webhook payloads, before they reach any model layer.

The sanitizer uses a two-pass regex approach:

  1. Strip complete ANSI/VT100 CSI sequences (\x1b[<params><letter>) and two-character escape sequences — these contain printable ASCII characters that the second pass would not catch.
  2. Strip any remaining non-printable ASCII characters (lone ESC bytes, other control characters, non-ASCII code points).
  3. Truncate to the column's max_length as a belt-and-suspenders guard.

Test plan

  • New regression test test_merge_event_author_email_with_ansi_sequences_is_sanitized in tests/sentry/integrations/gitlab/test_webhook.py — injects a production-style malformed email (valid address + 67 ANSI escape sequences, length > 200) into the webhook payload, posts it through the full webhook handler, and asserts that the CommitAuthor is created with the clean email and name.
  • Existing GitLab webhook tests continue to pass.

Generated by Claude Code

…ail/name

A GitLab MR webhook arrived with ANSI terminal escape sequences appended to
the commit author email (e.g. cursor-left/right sequences totalling ~170
extra bytes). The raw value was passed straight to
CommitAuthor.objects.get_or_create, where PostgreSQL's varchar(200) constraint
on the email column raised StringDataRightTruncation, failing the entire
webhook request.

Fix by sanitizing email and name strings at the point of extraction from the
webhook payload — before they reach any model or database layer — using a
two-pass regex: first strip complete ANSI/VT100 CSI sequences (which contain
printable ASCII characters that a single non-printable pass would miss), then
strip any remaining non-printable ASCII characters. Finally, truncate to the
column's max_length as a belt-and-suspenders guard.

Apply the same sanitization to push-event author name (push events already had
a length guard on email, but no control-character stripping on name).

Fixes SENTRY-5RKP.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ma5RaV2qEq4QrWH3gakKs5
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Jul 19, 2026
@billyvg

billyvg commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

this just affects a single user it looks like, not high priority

@billyvg billyvg closed this Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants