Skip to content

fix(webhook): validate custom headers as a control-char-free string map - #403

Merged
rmyndharis merged 1 commit into
mainfrom
fix/validate-webhook-headers
Jun 21, 2026
Merged

fix(webhook): validate custom headers as a control-char-free string map#403
rmyndharis merged 1 commit into
mainfrom
fix/validate-webhook-headers

Conversation

@rmyndharis

Copy link
Copy Markdown
Owner

Summary

The webhook headers field (Create + Update DTOs) was validated only with @IsObject() — it accepted any object shape with no per-entry checks. That allowed:

  • Header injection: a value containing CR/LF (e.g. "a\r\nX-Injected: 1") could attempt to inject extra headers into the outbound webhook request.
  • Silent delivery breakage: non-string values (numbers/booleans/nested objects) were coerced/mishandled at delivery time.

A new @IsHeaderMap() validator now requires a flat map of valid header names ([A-Za-z0-9-]+) to string values that are free of C0 control characters + DEL, and bounds the map (≤50 entries, value ≤1024 chars). The existing delivery-time reserved-name filter (sanitizeCustomHeaders) is unchanged — this is the complementary input-side guard.

Tests

  • webhook.dto.spec.ts: accepts a normal string map; rejects CR/LF values (injection), non-string values, invalid header names; UpdateWebhookDto enforces the same.
  • Full gate: lint 0 · build OK · 1071 unit · 26 e2e pass.

Risk

Low. Only rejects header maps that were already malformed or unsafe at delivery — surfaces the error at create/update time (400) instead of silently mangling or injecting at send time. Valid string headers are unaffected.

The webhook `headers` field was only @isObject — it accepted any shape with no
per-value validation, so a value containing CR/LF could attempt header injection
into the outbound request and non-string values silently broke delivery. Add an
@IsHeaderMap validator (Create + Update DTOs) that requires valid header names,
string values free of C0 control chars (the CR/LF injection vector), and bounds
the map (max 50 entries, value max 1024 chars). The delivery-time reserved-name
filter (sanitizeCustomHeaders) is unchanged.
@rmyndharis
rmyndharis merged commit dfa5f9f into main Jun 21, 2026
5 checks passed
@rmyndharis
rmyndharis deleted the fix/validate-webhook-headers branch June 21, 2026 12:41
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.

1 participant