Skip to content

feat: Selective Allow for cross-origin local navigation (#57)#86

Merged
ACK-J merged 6 commits into
mainfrom
cursor/selective-allow-57-afdc
Jul 12, 2026
Merged

feat: Selective Allow for cross-origin local navigation (#57)#86
ACK-J merged 6 commits into
mainfrom
cursor/selective-allow-57-afdc

Conversation

@ACK-J

@ACK-J ACK-J commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Problem

Clicking a link from an internet page to a local address (e.g. http://localhost:8080) is treated as a port scan because webRequest reports the external page as originUrl. That breaks legitimate workflows (Proxmox consoles, VPN dashboards, local dev links in docs).

Closes #57. Supersedes #74 (new implementation on current main, not a rebase of that draft).

Solution

For main_frame navigations to literal local/private URLs, open a Selective Allow popup instead of silently blocking:

Button Effect
Block Stays blocked; clears in-flight prompt state
Allow Once Session-only (Set, cleared on restart)
Always Allow Persists { origin, destination } under cross_origin_allowlist

Saved pairs are manageable from the settings page.

Subresources (fetch / XHR / iframes) and DNS-rebinding style portscans remain on the silent block + badge path.

Review fixes vs #74

  • Validate originalUrl is local and host matches destination before navigate/persist
  • Reuse the cancelled tab via tabs.update (fallback to tabs.create)
  • Dedupe in-flight popups per origin|destination
  • Guard against unsafe page path traversal in openSelectiveAllowPopup
  • Built on current requestFilter.js architecture (no conflict with main)
  • Unit tests for validation, session state, and popup helper

Test plan

  • npm test (641 passed)
  • Manual: from an external page, click http://localhost:8080 → popup appears
  • Allow Once → same tab navigates; second click in-session allowed
  • Always Allow → pair appears in settings; survives restart
  • Subresource to localhost still silently blocked
Open in Web Open in Cursor 

cursoragent and others added 6 commits July 12, 2026 01:57
When an external page links to a literal local address, prompt on
main_frame navigations instead of silently blocking. Allow Once is
session-only; Always Allow persists origin→destination pairs.

Hardens the allow path by validating that originalUrl is local and
matches the displayed destination, reuses the cancelled tab via
tabs.update, and dedupes in-flight prompts per origin/destination.

Closes #57. Supersedes #74.

Co-authored-by: Hacks and Hops <ACK-J@users.noreply.github.com>
Document the manual check in the README so reviewers can exercise
the main_frame prompt from a non-local origin.

Co-authored-by: Hacks and Hops <ACK-J@users.noreply.github.com>
Defer opening the decision UI outside the blocking webRequest stack,
fall back to a tab if the popup window fails, and show a notification
so the prompt is not easy to miss. Clarify in README/TestPortScans that
this UI is not the toolbar popup.

Co-authored-by: Hacks and Hops <ACK-J@users.noreply.github.com>
Clear pending when the decision window/tab is closed so chrome-dismiss
cannot permanently suppress re-prompts. Bind Allow Once/Always to a
server-issued promptId and the stored pending record instead of
client-supplied origin. Keep pending if only the notification fails,
clear it when validation rejects, and key file:// initiators by path.

Co-authored-by: Hacks and Hops <ACK-J@users.noreply.github.com>
Collapse pending tracking to one map, hardcode the decision page path,
and stop mirroring Always Allow into the session set so settings removals
take effect immediately. Require a bound UI id before keeping pending,
update the latest blocked URL/tab while a prompt is open, and revoke any
leftover session allows when the persisted list changes.

Co-authored-by: Hacks and Hops <ACK-J@users.noreply.github.com>
Use atomic ensurePendingPrompt so concurrent navigations share one
promptId/UI. Key blob/about initiators by full href, refuse data: URLs
for selective allow, and drop unused tabId from the decision page URL.

Co-authored-by: Hacks and Hops <ACK-J@users.noreply.github.com>
@ACK-J ACK-J marked this pull request as ready for review July 12, 2026 03:00
@ACK-J ACK-J merged commit d596922 into main Jul 12, 2026
1 check passed
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.

[BUG] Links to LAN resources from non-LAN pages are treated as portscan attempts

2 participants