Skip to content

fix: reject invalid hosts matched via path substrings - #31

Merged
Kikobeats merged 2 commits into
masterfrom
cursor/critical-bug-management-22ac
Aug 5, 2026
Merged

Kikobeats merged 2 commits into
masterfrom
cursor/critical-bug-management-22ac

Conversation

@cursor

@cursor cursor Bot commented Jul 28, 2026 •

Copy link
Copy Markdown
Contributor

Bug and impact

When matching runs with exact: false (IPv6, punycode, and previously text fragments), url-regex-safe can match a URL-looking substring in the path while the actual authority is not a valid HTTP host.

Concrete triggers that previously returned the href instead of false:

  • http://internal/https://example.com/#:~:text=x → authority is internal (http://internal/ alone is rejected)
  • http://metadata/https://example.com/#:~:text=x
  • http://xn--internal/https://example.com/

Callers that treat a truthy url-http result as a validated HTTP(S) URL can accept single-label / otherwise-rejected hosts because a valid URL appears later in the path.

This is distinct from #30 (credentialed-URL bypass). #30 rejects userinfo; this PR rejects invalid authorities accepted via unanchored path matches.

Root cause

  1. Text-fragment URLs unnecessarily disabled exact matching, even though exact: true already accepts them.
  2. For IPv6/punycode, unanchored matching of the full href can succeed on a path substring without validating the origin.

Fix

  • Keep exact matching enabled for text fragments.
  • When matching must be unanchored (IPv6/punycode), also require origin + '/' to match.
  • Add regression cases for the path-substring hosts above.

Validation

  • npm test passes (lint + Ava, 100% coverage)
Open in Web View Automation 

Note

Medium Risk
Changes URL acceptance rules for security-sensitive validation; behavior shifts for edge-case URLs (text fragments and IPv6/punycode) but is intended to reject previously dangerous false positives.

Overview
Tightens HTTP(S) URL validation so callers cannot treat a truthy result as a safe URL when the real authority is invalid but a second URL appears in the path (e.g. http://internal/https://example.com/).

Exact matching is no longer disabled for text-fragment hashes (#:~:text=), since that was unnecessary and forced looser regex behavior.

For IPv6 and punycode hosts (where url-regex-safe cannot use exact: true), validation now requires a second match on `${origin}/` after resetting regex.lastIndex, so a path substring cannot satisfy the check alone.

Regression tests cover internal, metadata, and punycode-style authorities with embedded https:// in the path.

Reviewed by Cursor Bugbot for commit 3f9ec94. Bugbot is set up for automated code reviews on this repo. Configure here.

@Kikobeats
Kikobeats marked this pull request as ready for review August 5, 2026 09:23
cursoragent and others added 2 commits August 5, 2026 17:25
When exact matching is disabled for IPv6/punycode URLs, url-regex-safe
can match a URL-looking substring in the path while the authority itself
is not a valid HTTP host. Stop treating text fragments as unanchored, and
require the origin to match whenever matching is unanchored.

Co-authored-by: kikohumanbeatbox <kikohumanbeatbox@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MTbj6CYXGsk6rhXx7J8SUP
@Kikobeats
Kikobeats force-pushed the cursor/critical-bug-management-22ac branch from 63a29dd to 3f9ec94 Compare August 5, 2026 15:26
@Kikobeats
Kikobeats merged commit 5162219 into master Aug 5, 2026
4 checks passed
@Kikobeats
Kikobeats deleted the cursor/critical-bug-management-22ac branch August 5, 2026 15:31
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