[GH-ISSUE #2840] [Bug] Browser inspection invents agent relations at non-HTML whitespace #1013

Closed
opened 2026-10-15 18:30:21 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @zhangguiping-xydt on GitHub (Oct 13, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/2840

Before submitting

  • I searched the open and closed issues and PRs for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction — passive browser inspection

Observed behavior

inspect-web-page and the MCP inspect_web_page tool report an agent hint for <link rel="alternate&#xA0;mcp" href="/nbsp">. Chrome treats alternate\u00a0mcp as one relation token, so this element does not declare the mcp relation.

The same false classification occurs for vertical tab (U+000B), em space (U+2003), and BOM (U+FEFF). In a real Chrome reproduction containing four such links and one link with four valid agent relations, both compiled CLI and MCP returned eight hints instead of four.

Reproduction

  1. Serve this HTML as UTF-8 on localhost and open it in Chrome with a loopback CDP endpoint:
<!doctype html><meta charset="utf-8"><title>Rel token probe</title>
<link rel="alternate&#xA0;mcp" href="/nbsp">
<link rel="alternate&#xB;model-context" href="/vertical-tab">
<link rel="alternate&#x2003;ai-plugin" href="/em-space">
<link rel="&#xFEFF;service-desc" href="/bom">
<link rel="alternate MCP&#x9;model-context&#xA;ai-plugin&#xC;service-desc&#xD;" href="/actual">
  1. Read Chrome's tokenization:
Array.from(document.querySelectorAll('link'), e => [...e.relList])
  1. Run rea inspect-web-page <cdp-endpoint> <target-id> --observation-ms 0 --format json, or call inspect_web_page with cdp_endpoint, target_id, allowed_origins: [the localhost origin], and observation_ms: 0.
  2. Inspect normalized_result.metadata.agent_hints.

Expected behavior

Only the four supported relations on /actual should produce dom_link_rel hints. HTML relation tokens are separated by ASCII whitespace: U+0009, U+000A, U+000C, U+000D, and U+0020. Other whitespace characters must remain part of the token. The URLs of all five links should remain in dom_urls.

Impact and scope

False page-declared agent/service hints contaminate the inspection Evidence and can misdirect an analyst or agent investigating a web application. The inspection remains passive; this reproduction does not establish automatic connections to the reported endpoints. Ordinary links and valid relation declarations are unaffected.

REA version

Source revision beca34f52258b7b25d72c160ae6fffa1cc3c034b (built runtime).

Runtime and platform

Linux x86_64, Node.js 24.18.0, Google Chrome 138.0.7204.157.

Interface / earliest failure stage

Both CLI and MCP / capture or observation.

Relevant output or evidence

Chrome returns one token for each invalid case:

[
  ["alternate\u00a0mcp"],
  ["alternate\u000bmodel-context"],
  ["alternate\u2003ai-plugin"],
  ["\ufeffservice-desc"],
  ["alternate", "MCP", "model-context", "ai-plugin", "service-desc"]
]

Both adapters incorrectly include these additional hints (URL origin omitted here):

mcp            /nbsp
model-context  /vertical-tab
ai-plugin      /em-space
service-desc   /bom

Analysis

Source-derived cause: domMetadata in src/browser/CdpCaptureDocuments.ts splits rel with JavaScript /\s+/u, which recognizes more whitespace than HTML. The shared producer feeds both CLI and MCP. Four added regression cases fail on the revision above with exactly these extra declarations; the ASCII-whitespace controls pass.

Originally created by @zhangguiping-xydt on GitHub (Oct 13, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2840 ### Before submitting - [x] I searched the open and closed issues and PRs for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Evidence, artifacts, or reconstruction — passive browser inspection ### Observed behavior `inspect-web-page` and the MCP `inspect_web_page` tool report an agent hint for `<link rel="alternate&#xA0;mcp" href="/nbsp">`. Chrome treats `alternate\u00a0mcp` as one relation token, so this element does not declare the `mcp` relation. The same false classification occurs for vertical tab (U+000B), em space (U+2003), and BOM (U+FEFF). In a real Chrome reproduction containing four such links and one link with four valid agent relations, both compiled CLI and MCP returned **eight hints instead of four**. ### Reproduction 1. Serve this HTML as UTF-8 on localhost and open it in Chrome with a loopback CDP endpoint: ```html <!doctype html><meta charset="utf-8"><title>Rel token probe</title> <link rel="alternate&#xA0;mcp" href="/nbsp"> <link rel="alternate&#xB;model-context" href="/vertical-tab"> <link rel="alternate&#x2003;ai-plugin" href="/em-space"> <link rel="&#xFEFF;service-desc" href="/bom"> <link rel="alternate MCP&#x9;model-context&#xA;ai-plugin&#xC;service-desc&#xD;" href="/actual"> ``` 2. Read Chrome's tokenization: ```js Array.from(document.querySelectorAll('link'), e => [...e.relList]) ``` 3. Run `rea inspect-web-page <cdp-endpoint> <target-id> --observation-ms 0 --format json`, or call `inspect_web_page` with `cdp_endpoint`, `target_id`, `allowed_origins: [the localhost origin]`, and `observation_ms: 0`. 4. Inspect `normalized_result.metadata.agent_hints`. ### Expected behavior Only the four supported relations on `/actual` should produce `dom_link_rel` hints. HTML relation tokens are separated by ASCII whitespace: U+0009, U+000A, U+000C, U+000D, and U+0020. Other whitespace characters must remain part of the token. The URLs of all five links should remain in `dom_urls`. ### Impact and scope False page-declared agent/service hints contaminate the inspection Evidence and can misdirect an analyst or agent investigating a web application. The inspection remains passive; this reproduction does not establish automatic connections to the reported endpoints. Ordinary links and valid relation declarations are unaffected. ### REA version Source revision `beca34f52258b7b25d72c160ae6fffa1cc3c034b` (built runtime). ### Runtime and platform Linux x86_64, Node.js 24.18.0, Google Chrome 138.0.7204.157. ### Interface / earliest failure stage Both CLI and MCP / capture or observation. ### Relevant output or evidence Chrome returns one token for each invalid case: ```json [ ["alternate\u00a0mcp"], ["alternate\u000bmodel-context"], ["alternate\u2003ai-plugin"], ["\ufeffservice-desc"], ["alternate", "MCP", "model-context", "ai-plugin", "service-desc"] ] ``` Both adapters incorrectly include these additional hints (URL origin omitted here): ```text mcp /nbsp model-context /vertical-tab ai-plugin /em-space service-desc /bom ``` ### Analysis Source-derived cause: `domMetadata` in `src/browser/CdpCaptureDocuments.ts` splits `rel` with JavaScript `/\s+/u`, which recognizes more whitespace than HTML. The shared producer feeds both CLI and MCP. Four added regression cases fail on the revision above with exactly these extra declarations; the ASCII-whitespace controls pass.
bsakaguchi 2026-10-15 18:30:21 +00:00
Author
Owner

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

Verified the reported defect is addressed on main by f6905719c3.

Root cause and resolution: HTML relation tokens were split with JavaScript Unicode whitespace semantics rather than HTML's ASCII whitespace set.

Validation: src/browser/CdpCaptureDocuments.baseUrl.test.ts — splits link relations only on HTML ASCII whitespace: NBSP, VT, em-space, and BOM do not split relation tokens; tab does, producing exactly mcp and service-desc.

Evidence: CI run 500e: exact source/test owner unchanged and assertion passed.

Verification scope: Producer protocol fixture proves tokenization; original issue separately supplied real Chrome CLI/MCP reproduction, but current real-browser lane does not specifically repeat this Unicode case.

Current main CI has separate failures under repair; this closure does not claim the complete main workflow is green.

<!-- gh-comment-id:6162502464 --> @morluto commented on GitHub (Oct 14, 2026): Verified the reported defect is addressed on main by f6905719c3c80d829037e509d6e46129b131d893. Root cause and resolution: HTML relation tokens were split with JavaScript Unicode whitespace semantics rather than HTML's ASCII whitespace set. Validation: `src/browser/CdpCaptureDocuments.baseUrl.test.ts` — `splits link relations only on HTML ASCII whitespace`: NBSP, VT, em-space, and BOM do not split relation tokens; tab does, producing exactly `mcp` and `service-desc`. Evidence: CI run 500e: exact source/test owner unchanged and assertion passed. Verification scope: Producer protocol fixture proves tokenization; original issue separately supplied real Chrome CLI/MCP reproduction, but current real-browser lane does not specifically repeat this Unicode case. Current main CI has separate failures under repair; this closure does not claim the complete main workflow is green.
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#1013
No description provided.