[GH-ISSUE #183] Loopback browser scope misclassifies IPv6 ::1 URLs #129

Closed
opened 2026-10-15 18:21:24 +00:00 by bsakaguchi · 2 comments
Owner

Originally created by @morluto on GitHub (Jul 14, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/183

Problem

parseConfig/browserNetworkScope currently treats IPv6 loopback as external because it checks hostname === "127.0.0.1" || hostname === "[::1]". URL.hostname for http://[::1]:8080 is "::1" (Node canonical form), so an IPv6 loopback origin can be classified as external.

Impact

  • Permissions on browser artifacts may be overly permissive/incorrect (e.g., browserNetworkScope becomes external).
  • Behavior diverges from isLiteralLoopback in src/domain/browserObservation.ts, which already treats ::1 as loopback.
  • Affects consistency across MCP/CLI permission handling for local browser analysis.

Reproduction

const cfg = parseConfig({ browserNetworkScope: "127.0.0.1" /* via config env */ });
const parsed = parseBrowserOrigin("http://[::1]:8080", 0); // internal check path eventually compares host against browserNetworkScope logic

Using http://[::1]:port currently follows the same external scope path because the hostname string is ::1 not [::1].

Suggested fix

Normalize URL.hostname comparisons for IPv6 loopback, e.g. treat both ::1 and [::1] as loopback, or rely on robust loopback helpers used by observation parsing.

Evidence

  • src/config.ts in parseBrowserOrigin / browserNetworkScope host check
  • src/domain/browserObservation.ts isLiteralLoopback() already checks host === "::1" and hostname variants.
Originally created by @morluto on GitHub (Jul 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/183 ### Problem `parseConfig`/`browserNetworkScope` currently treats IPv6 loopback as external because it checks `hostname === "127.0.0.1" || hostname === "[::1]"`. `URL.hostname` for `http://[::1]:8080` is `"::1"` (Node canonical form), so an IPv6 loopback origin can be classified as external. ### Impact - Permissions on browser artifacts may be overly permissive/incorrect (e.g., `browserNetworkScope` becomes `external`). - Behavior diverges from `isLiteralLoopback` in `src/domain/browserObservation.ts`, which already treats `::1` as loopback. - Affects consistency across MCP/CLI permission handling for local browser analysis. ### Reproduction ```ts const cfg = parseConfig({ browserNetworkScope: "127.0.0.1" /* via config env */ }); const parsed = parseBrowserOrigin("http://[::1]:8080", 0); // internal check path eventually compares host against browserNetworkScope logic ``` Using `http://[::1]:port` currently follows the same external scope path because the hostname string is `::1` not `[::1]`. ### Suggested fix Normalize `URL.hostname` comparisons for IPv6 loopback, e.g. treat both `::1` and `[::1]` as loopback, or rely on robust loopback helpers used by observation parsing. ### Evidence - `src/config.ts` in `parseBrowserOrigin` / `browserNetworkScope` host check - `src/domain/browserObservation.ts` `isLiteralLoopback()` already checks `host === "::1"` and hostname variants.
bsakaguchi 2026-10-15 18:21:24 +00:00
Author
Owner

@morluto commented on GitHub (Jul 14, 2026):

Additional affected path: BrowserObservationService.ts contains the same IPv6 loopback check bug as config scope parsing. At line 123 it currently treats IPv6 loopback as '[::1]' (with brackets), but Node URL.hostname provides '::1' for URLs like http://[::1]:port, so browser observation scope validation can incorrectly reject local targets.

This is the same root cause as this issue, but in the application/browser scope gate path.

<!-- gh-comment-id:4965914642 --> @morluto commented on GitHub (Jul 14, 2026): Additional affected path: `BrowserObservationService.ts` contains the same IPv6 loopback check bug as config scope parsing. At line 123 it currently treats IPv6 loopback as `'[::1]'` (with brackets), but Node `URL.hostname` provides `'::1'` for URLs like `http://[::1]:port`, so browser observation scope validation can incorrectly reject local targets. This is the same root cause as this issue, but in the application/browser scope gate path.
Author
Owner

@morluto commented on GitHub (Jul 17, 2026):

Implemented on main via the shared isLiteralLoopbackHostname helper. Both config browserNetworkScope and BrowserObservationService now recognize canonical ::1, with IPv6 coverage in tests/config.test.ts and tests/browserObservation.test.ts.

<!-- gh-comment-id:5001297726 --> @morluto commented on GitHub (Jul 17, 2026): Implemented on main via the shared isLiteralLoopbackHostname helper. Both config browserNetworkScope and BrowserObservationService now recognize canonical ::1, with IPv6 coverage in tests/config.test.ts and tests/browserObservation.test.ts.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#129
No description provided.