Skip to content

fix(webmention): remove polynomial-redos in Link header regex - #436

Merged
davidwkeith merged 1 commit into
mainfrom
claude/github-advanced-security-issue-7fsp8s
Jul 24, 2026
Merged

fix(webmention): remove polynomial-redos in Link header regex#436
davidwkeith merged 1 commit into
mainfrom
claude/github-advanced-security-issue-7fsp8s

Conversation

@davidwkeith

Copy link
Copy Markdown
Owner

Summary

Fixes GitHub code scanning alert #13 (js/polynomial-redos, CodeQL): parseLinkHeader's regex in packages/webmention/src/html.ts had \s* immediately before (.*)$. Since \s is a subset of what . matches, the two quantifiers were ambiguous about how to split the input between them, allowing a crafted HTTP Link header value — attacker-controlled, since it's fetched from whatever server a webmention source/target points at — to force excessive (polynomial) regex backtracking.

Fix: drop the redundant \s*. Leading whitespace on each ;-delimited parameter is already stripped by extractRel's own per-parameter ^\s*rel\s*=...$ regex, so parsing behavior is unchanged — confirmed by the existing parseLinkHeader test suite, which still passes.

Packages affected

  • @dwk/webmention

Checklist

  • Read the relevant spec(s) under spec/packages/ and updated them if behaviour changed — not applicable, no behavior change, pure regex hardening
  • Added/updated colocated tests (src/*.test.ts) — not applicable, existing html.test.ts coverage already exercises parseLinkHeader and continues to pass
  • Ran the local CI gate: pnpm lint && pnpm format:check && pnpm typecheck && pnpm build && pnpm test
  • Added a changeset (pnpm changeset) if this touches a publishable package
  • Updated catalog.json / conformance/status.json if this adds a new mountable worker or changes conformance status — not applicable, no new worker or conformance status change

Generated by Claude Code

CodeQL (js/polynomial-redos) flagged the `\s*` immediately before
`(.*)$` in parseLinkHeader's regex: since `\s` is a subset of what `.`
matches, a crafted Link header value (attacker-controlled, fetched
during webmention discovery/verification) with runs of whitespace
could force excessive backtracking. Drop the redundant `\s*` — leading
whitespace on each parameter is already trimmed by extractRel's
per-parameter `rel` regex.

@davidwkeith davidwkeith left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Reviewed the diff and the surrounding html.ts parsing logic.

Correctness: the fix is sound. Removing the redundant \s* before (.*)$ eliminates the ambiguous-quantifier ReDoS (\s is a subset of ., so the two greedy quantifiers could split the match in exponentially many ways on crafted whitespace runs). Behavior is unchanged: splitParams already tokenizes on ;, and extractRel's own ^\s*rel\s*=...$ regex strips any leading whitespace on the captured parameter string, so the second capture group losing its explicit whitespace-trim doesn't change what extractRel/splitTokens ultimately see. Traced the whole path (splitLinksparseLinkHeaderextractRelsplitTokens) and confirmed no other caller depends on match[2] being pre-trimmed.

CONTRIBUTING.md conformance:

  • PR title fix(webmention): remove polynomial-redos in Link header regex — correct Conventional Commits form (lowercase type, parenthesized scope, uncapitalized subject, no trailing period).
  • Changeset added (@dwk/webmention patch) — appropriate bump for a behavior-preserving security hardening fix.
  • Template headings (Summary/Packages affected/Checklist) kept verbatim; unchecked items carry one-line reasons rather than being deleted, per the contributing guide.
  • Scope is minimal and focused — single-line regex change plus changeset, no unrelated cleanup.

No changes requested. This looks ready to merge as-is.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

The github-advanced-security check failure here isn't related to this PR's diff — it's GitHub's automatic Copilot Autofix for code scanning agent (workflow path dynamic/agents/github-advanced-security), which runs on every PR to try to suggest fixes for open code-scanning alerts.

Job logs (run 30105424542) show it failing at the model-selection step, before analyzing any code:

CAPIError: 400 {"error":{"message":"The requested model is not supported.","code":"model_not_supported","param":"model","type":"invalid_request_error"}}

It's requesting sweagent-capi:claude-opus-4.6 and being rejected — consistent with no Copilot seat/license being provisioned for this account/org. Since this check is bot-triggered infrastructure rather than a job defined in .github/workflows/, there's no code change in this repo that can fix it; it needs to be addressed in Settings → Code security and analysis → Copilot Autofix (toggle it off) or by provisioning a Copilot license, whichever this account intends.

Not blocking on this PR's actual content — the ci.yml gate (lint/format/typecheck/build/test) is what validates the regex fix itself.


Generated by Claude Code

@davidwkeith
davidwkeith merged commit f34b247 into main Jul 24, 2026
8 of 9 checks passed
@davidwkeith
davidwkeith deleted the claude/github-advanced-security-issue-7fsp8s branch July 24, 2026 16:18
davidwkeith added a commit that referenced this pull request Jul 24, 2026
parseBasicAuthorization's /^basic\s+(.+)$/i had \s+ immediately before
(.+)$, ambiguous over runs of whitespace in the same way the already-fixed
webmention Link header regex (#436) was. Replaced with an unambiguous
search()/slice() split.

Closes GitHub code scanning alert #11 (js/polynomial-redos).

Co-authored-by: Claude <noreply@anthropic.com>
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