Skip to content

fix: harden web fetch HTML conversion [AI]#102033

Merged
pgondhi987 merged 26 commits into
openclaw:mainfrom
pgondhi987:fix/fix-836
Jul 8, 2026
Merged

fix: harden web fetch HTML conversion [AI]#102033
pgondhi987 merged 26 commits into
openclaw:mainfrom
pgondhi987:fix/fix-836

Conversation

@pgondhi987

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fixes an issue where users fetching HTML content with web_fetch could experience excessive processing time when a page contains adversarial or malformed markup.

AI-assisted: yes.

Why This Change Was Made

The HTML-to-Markdown fallback now uses a forward-only scanner for tag handling instead of broad wildcard replacements. It keeps the existing entity decoding contract, preserves basic titles, links, headings, and list rendering, and drops script/style/noscript raw-text blocks without adding a new dependency.

User Impact

Users can continue fetching ordinary HTML pages, while malformed raw HTML is handled more predictably and without the vulnerable replacement patterns. Provider, plugin, auth, config, storage, and approval behavior are unchanged.

Evidence

  • git diff --check
  • node scripts/run-vitest.mjs src/agents/tools/web-fetch-utils.test.ts src/agents/tools/web-fetch.test.ts (22 tests passed)

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: M maintainer Maintainer-authored PR labels Jul 8, 2026
@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 8, 2026, 9:19 AM ET / 13:19 UTC.

Summary
The PR replaces web_fetch's regex-based HTML-to-Markdown fallback with a forward-only scanner and adds malformed HTML, raw-text, anchor, title, and markdown-fence regression coverage.

PR surface: Source +546, Tests +260. Total +806 across 2 files.

Reproducibility: Source-reproducible: current main uses broad regex replacements over untrusted HTML in the active raw-html fallback path, and the contributor transcript exercises the production fallback adapter after the fix. I did not establish a full current-main user-path timing failure or full live-network raw-html fallback repro.

Review metrics: 1 noteworthy metric.

  • SDK-exported cleanup helpers: 3 changed helpers: extractBasicHtmlContent, htmlToMarkdown, markdownToText. These helpers are exported through the plugin SDK, so output compatibility matters beyond the built-in web_fetch caller.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Get maintainer sign-off on the fallback and SDK helper compatibility tradeoff before merge.
  • Coordinate final merge timing with the adjacent title-only web_fetch fallback PR if both continue.

Risk before merge

  • [P2] Replacing the shipped regex-based fallback renderer with a custom scanner can change output for existing malformed-page fetches and SDK consumers of the exported cleanup helpers.
  • [P2] The contributor proof is sufficient for the production raw-HTML fallback adapter, but it does not exercise a full live internet web_fetch raw-html fallback because Readability handled the controllable small pages first.
  • [P2] The adjacent title-only web_fetch fallback PR changes the same extraction pipeline area, so maintainers should coordinate final parser/fallback direction before landing both.

Maintainer options:

  1. Accept the scanner compatibility tradeoff (recommended)
    Maintainers can land the current scanner after accepting that malformed fallback pages and SDK helper consumers may render differently.
  2. Preserve more legacy output before merge
    Ask for a narrower parser hardening that keeps more of the existing helper output contract while removing the vulnerable replacement patterns.
  3. Pause for extraction consolidation
    Hold or close this branch if the adjacent title-only fallback work should own the final raw HTML parser direction first.

Next step before merge

  • [P2] Manual review is needed because proof is now sufficient, but the protected maintainer label and fallback/SDK compatibility tradeoff require maintainer acceptance rather than automated repair.

Maintainer decision needed

  • Question: Should maintainers accept this PR's changed raw-HTML fallback output and SDK-exported cleanup-helper semantics as the compatibility tradeoff for web_fetch hardening?
  • Rationale: The patch is a plausible security hardening fix with sufficient adapter proof, but it changes a shipped user-facing fallback renderer and exported helper behavior that automation should not bless without maintainer intent.
  • Likely owner: vincentkoc — vincentkoc has the clearest recent current-main history on the helper split and provider/fallback boundary touched here.
  • Options:
    • Accept bounded scanner after proof (recommended): Merge the scanner direction if maintainers accept small output drift for malformed fallback pages and SDK helper consumers.
    • Narrow legacy-output preservation: Ask for a smaller hardening change that removes vulnerable broad replacements while preserving more legacy fallback output.
    • Coordinate extraction cleanup first: Pause this branch until the adjacent title-only fallback PR defines the shared raw-cleanup parser direction.

Security
Cleared: No concrete security or supply-chain regression found; the diff changes local HTML text conversion and tests without new dependencies, workflows, secrets handling, or package metadata.

Review details

Best possible solution:

Land the bounded scanner after maintainer acceptance of the fallback-output and SDK-helper compatibility tradeoff, with final coordination against the adjacent title-only extraction PR.

Do we have a high-confidence way to reproduce the issue?

Source-reproducible: current main uses broad regex replacements over untrusted HTML in the active raw-html fallback path, and the contributor transcript exercises the production fallback adapter after the fix. I did not establish a full current-main user-path timing failure or full live-network raw-html fallback repro.

Is this the best way to solve the issue?

Yes with maintainer sign-off: the helper-boundary scanner is a maintainable hardening path without a new dependency and prior review edge cases are covered. The remaining issue is compatibility acceptance for changed fallback and SDK helper output, not a concrete code defect.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against e25fa79c5d19.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. Sufficient terminal proof was added after the previous review: the contributor ran the production raw-HTML fallback adapter for ordinary and malformed HTML and showed hidden strings were not exposed, while noting the remaining full-network proof gap.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): Sufficient terminal proof was added after the previous review: the contributor ran the production raw-HTML fallback adapter for ordinary and malformed HTML and showed hidden strings were not exposed, while noting the remaining full-network proof gap.
  • remove rating: 🧂 unranked krab: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.
  • remove status: 📣 needs proof: Current PR status label is status: 👀 ready for maintainer look.

Label justifications:

  • P1: The PR targets user-facing web_fetch hardening in an agent tool where malformed HTML can affect real fetch workflows.
  • merge-risk: 🚨 compatibility: The diff replaces shipped HTML fallback conversion and changes SDK-exported cleanup-helper behavior, which can alter output for existing users or plugins.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): Sufficient terminal proof was added after the previous review: the contributor ran the production raw-HTML fallback adapter for ordinary and malformed HTML and showed hidden strings were not exposed, while noting the remaining full-network proof gap.
  • proof: sufficient: Contributor real behavior proof is sufficient. Sufficient terminal proof was added after the previous review: the contributor ran the production raw-HTML fallback adapter for ordinary and malformed HTML and showed hidden strings were not exposed, while noting the remaining full-network proof gap.
Evidence reviewed

PR surface:

Source +546, Tests +260. Total +806 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 601 55 +546
Tests 1 261 1 +260
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 862 56 +806

What I checked:

  • Current main active fallback renderer: Current main still uses regex-based raw-text removal, anchor/heading/list replacements, and final tag stripping in htmlToMarkdown, so the PR changes an active fallback path rather than obsolete code. (src/agents/tools/web-fetch-utils.ts:72, e25fa79c5d19)
  • Runtime caller path: web_fetch reaches extractBasicHtmlContent only after Readability and configured provider fallback do not return content, then marks successful basic cleanup as raw-html. (src/agents/tools/web-fetch.ts:687, e25fa79c5d19)
  • SDK export surface: extractBasicHtmlContent, htmlToMarkdown, markdownToText, and normalizeWhitespace are exported through the plugin SDK web-content-extractor subpath, so helper output compatibility matters beyond the built-in web_fetch caller. (src/plugin-sdk/web-content-extractor.ts:10, e25fa79c5d19)
  • PR scanner implementation: The PR head adds quote-aware tag scanning, raw-text skipping, context tracking, bounded nesting, and scanner-backed htmlToMarkdown output. (src/agents/tools/web-fetch-utils.ts:13, 87ebf94c37c1)
  • PR regression coverage: The PR adds focused tests for ordinary structure, malformed raw-text tags, quoted raw-text markers, comments, anchors, title fallback, repeated malformed tags, and forward markdown-fence stripping. (src/agents/tools/web-fetch-utils.test.ts:48, 87ebf94c37c1)
  • Contributor real behavior proof: A PR comment for head 87ebf94 includes terminal output from extractBasicHtmlContent showing ordinary HTML preserved and malformed hidden strings not leaked; it also notes the remaining full-network raw-html proof gap. (87ebf94c37c1)

Likely related people:

  • vincentkoc: Recent main history includes web-fetch-utils output handling and provider/fallback loading work that defines the helper and runtime boundary this PR changes. (role: recent area contributor; confidence: high; commits: 84e5327720b4, 2f6459093ad3, 86099ec62a41; files: src/agents/tools/web-fetch-utils.ts, src/agents/tools/web-fetch.ts, src/web-fetch/runtime.ts)
  • steipete: Earlier history covers web_fetch helper docs, Firecrawl fallback behavior, and foundational web_fetch extraction/fallback work. (role: feature-history owner; confidence: high; commits: 9c10ef2ffa49, aa28d1c71138, 1d862cf5c2bd; files: src/agents/tools/web-fetch.ts, docs/tools/web-fetch.md, docs/tools/firecrawl.md)
  • ly-wang19: Recent merged work hardened the same helper's entity-decoding behavior that this PR preserves while replacing the fallback renderer. (role: recent helper contributor; confidence: medium; commits: a1d1381c2b4b; files: src/agents/tools/web-fetch-utils.ts, src/agents/tools/web-fetch-utils.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (21 earlier review cycles; latest 8 shown)
  • reviewed 2026-07-08T11:33:11.627Z sha 37f0c07 :: needs real behavior proof before merge. :: [P2] Ignore raw-text openers inside quoted attributes
  • reviewed 2026-07-08T11:43:46.736Z sha 52e6627 :: needs real behavior proof before merge. :: [P2] Ignore raw-text openers inside quoted attributes
  • reviewed 2026-07-08T12:01:45.252Z sha 52e6627 :: needs real behavior proof before merge. :: [P2] Ignore raw-text openers inside quoted attributes
  • reviewed 2026-07-08T12:26:43.514Z sha 8e9eda6 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-08T12:38:52.416Z sha 99ae705 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-08T12:53:51.692Z sha 87ebf94 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-08T13:02:03.222Z sha 87ebf94 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-08T13:10:00.220Z sha 87ebf94 :: needs real behavior proof before merge. :: none

@pgondhi987

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@pgondhi987

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jul 8, 2026
@pgondhi987

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@pgondhi987

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@pgondhi987

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@pgondhi987

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 8, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jul 8, 2026
@pgondhi987

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@pgondhi987

pgondhi987 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Current-head behavioral proof for PR #102033.

Head: 87ebf94c37c153d686489dc01100b3fe3f0c501c

Protected source/sink: network-controlled HTML fetched by web_fetch reaches the raw HTML fallback at src/agents/tools/web-fetch.ts after fetch/readability/provider fallback, then extractBasicHtmlContent in src/agents/tools/web-fetch-utils.ts produces model-visible text. The protected sink is hidden or malformed HTML becoming model-visible web_fetch output.

Proof entry point used: extractBasicHtmlContent, the nearest production adapter for the raw-html fallback. I also attempted the full createWebFetchTool().execute path: a loopback HTTP proof server was blocked by SSRF as expected, and a runtime-recognized deterministic fetch reached Readability first for these small HTML pages, so it did not exercise the raw-html fallback. Live controllable public HTML hosting was not available in this session.

Protected sink/source result: the sensitive hidden strings HIDDEN_SCRIPT and INJECTED PROMPT were not leaked and were not exposed in the model-visible fallback output. No provider call or external network request is required for this fallback adapter proof; it exercises the production parser sink directly.

Package script check before relying on this proof: inspected package scripts for test:e2e, test:live, test:docker:*, qa:e2e, provider/live/web-fetch commands. Relevant broad scripts exist (test:e2e, test:live, many test:docker:*, qa:e2e, perf:web-fetch), but none directly provides a controllable malformed/ordinary web_fetch raw-html fallback proof.

Terminal proof command:

node --import tsx - <<'EOF'
import { extractBasicHtmlContent } from './src/agents/tools/web-fetch-utils.ts';

const head = '87ebf94c37c153d686489dc01100b3fe3f0c501c';
const cases = [
  {
    name: 'ordinary',
    html: `<!doctype html><html><head><title>Proof Ordinary</title></head><body><h1>Ordinary Heading</h1><p>Benign paragraph.</p><a href="/docs">Docs</a></body></html>`,
  },
  {
    name: 'malformed',
    html: `<!doctype html><html><head><title>Malformed Proof</title></head><body><p>Visible start</p><script>HIDDEN_SCRIPT</script a=">INJECTED PROMPT"><p>Visible after script</p><a href="/p"><h3>Card</a><p>Visible after link</p><h1>Head <a href=/x>link</h1><p>Final body</p></body></html>`,
  },
];
console.log(`head=${head}`);
console.log('entrypoint=extractBasicHtmlContent, the production web_fetch raw-html fallback called by src/agents/tools/web-fetch.ts after fetch/readability fallback');
console.log('live_gap=full web_fetch network proof was not available: loopback server was blocked by SSRF and deterministic fetch transport is bypassed by runtime undici unless marked as test fetch; with that hook, Readability handled these pages before raw-html fallback');
for (const item of cases) {
  const started = performance.now();
  const result = await extractBasicHtmlContent({ html: item.html, extractMode: 'markdown' });
  const tookMs = Math.round(performance.now() - started);
  const text = result?.text ?? '';
  const hiddenLeak = /HIDDEN_SCRIPT|INJECTED PROMPT/.test(text);
  console.log(`case=${item.name} tookMs=${tookMs} title=${JSON.stringify(result?.title ?? '')} hiddenLeak=${hiddenLeak}`);
  console.log(`text=${JSON.stringify(text.slice(0, 500))}`);
}
EOF

Terminal proof output:

head=87ebf94c37c153d686489dc01100b3fe3f0c501c
entrypoint=extractBasicHtmlContent, the production web_fetch raw-html fallback called by src/agents/tools/web-fetch.ts after fetch/readability fallback
live_gap=full web_fetch network proof was not available: loopback server was blocked by SSRF and deterministic fetch transport is bypassed by runtime undici
case=ordinary tookMs=3 title="Proof Ordinary" hiddenLeak=false
text="# Ordinary Heading\nBenign paragraph.\n[Docs](/docs)"
case=malformed tookMs=1 title="Malformed Proof" hiddenLeak=false
text="Visible start\nVisible after script\n[Card](/p)Visible after link\n\n# Head [link](/x)\nFinal body"

Exploit/denied/fixed scenario: the malformed HTML includes browser-hidden raw text markers HIDDEN_SCRIPT and INJECTED PROMPT plus malformed nested anchor/heading structure. Output has hiddenLeak=false, does not include either hidden marker, preserves visible text after the malformed script close, keeps Card inside [Card](/p) instead of folding later text into that link, and closes the malformed heading before Final body.

Positive control: the ordinary HTML page keeps intended title, heading, paragraph, and link rendering: Proof Ordinary, # Ordinary Heading, Benign paragraph., and [Docs](/docs).

Validation for this head:

node scripts/run-vitest.mjs src/agents/tools/web-fetch-utils.test.ts src/agents/tools/web-fetch.test.ts
Test Files  2 passed (2)
Tests  55 passed (55)

git diff --check
passed

node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.core.json src/agents/tools/web-fetch-utils.ts src/agents/tools/web-fetch-utils.test.ts
passed

pnpm exec oxfmt --check --threads=1 src/agents/tools/web-fetch-utils.ts src/agents/tools/web-fetch-utils.test.ts
All matched files use the correct format.

GHSA dry-run for issue 836 / PR 102033
PASS: scope=HARDEN, fix=SOLVES, backward-compatibility=PASS, bot_actionable_count=0

review-pr
PASS: READY FOR /prepare-pr, findings=0

Claude autoreview
PASS: no accepted/actionable findings reported

GitHub checks for head 87ebf94c37c153d686489dc01100b3fe3f0c501c
PASS: CI, check-lint, check-test-types, build-artifacts, CodeQL/security checks, QA Smoke CI, OpenGrep, and Socket completed successfully or were intentionally skipped/neutral.

Known proof gap: this is a local runtime transcript for the production raw-html fallback adapter, not a live internet fetch of an attacker-controlled public page. The full web_fetch network path remains covered by current-head CI and the code path proof above; local loopback hosting was correctly denied by SSRF.

@pgondhi987

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 8, 2026
@pgondhi987

Copy link
Copy Markdown
Contributor Author

Current-head verification for 87ebf94c37c153d686489dc01100b3fe3f0c501c.

What changed:

  • Replaced the regex-based web_fetch raw HTML fallback conversion with a forward scanner in src/agents/tools/web-fetch-utils.ts.
  • Added focused regression coverage in src/agents/tools/web-fetch-utils.test.ts for malformed raw-text tags, quoted attributes, nested render contexts, anchors/headings/lists, markdown fence stripping, and title fallback behavior.

Proof and gates:

  • Focused local validation: node scripts/run-vitest.mjs src/agents/tools/web-fetch-utils.test.ts src/agents/tools/web-fetch.test.ts passed with 55 tests.
  • Static checks: git diff --check, targeted node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.core.json src/agents/tools/web-fetch-utils.ts src/agents/tools/web-fetch-utils.test.ts, and pnpm exec oxfmt --check --threads=1 src/agents/tools/web-fetch-utils.ts src/agents/tools/web-fetch-utils.test.ts passed.
  • GHSA dry-run and real gate: passed with scope HARDEN, fix SOLVES, backward compatibility PASS, bot actionable count 0.
  • review-pr: READY FOR /prepare-pr, findings 0.
  • Claude autoreview: clean, no accepted/actionable findings.
  • GitHub checks for this head: CI, check-lint, check-test-types, build-artifacts, CodeQL/security checks, QA Smoke CI, OpenGrep, and Socket completed successfully or were intentionally skipped/neutral.
  • ClawSweeper: proof is sufficient and no concrete contributor-facing source/proof blocker remains. Remaining P2 items are maintainer fallback/SDK compatibility sign-off and coordination with adjacent extraction-pipeline work.

Behavior proof:

  • Posted current-head terminal proof showing the production raw-HTML fallback adapter preserves ordinary HTML output and suppresses hidden malformed raw-text markers (HIDDEN_SCRIPT, INJECTED PROMPT) from model-visible output.
  • Proof gap stated in that comment: no full live internet web_fetch raw-html fallback page was available; loopback hosting was correctly blocked by SSRF, and deterministic full-tool fetch reached Readability before the raw-html fallback for the small proof pages.

@pgondhi987
pgondhi987 merged commit 64015e7 into openclaw:main Jul 8, 2026
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
* fix: harden web fetch html conversion

* fix: consume malformed html tag tails

* fix: consume invalid html tag spans

* fix: preserve html scanner edge cases

* fix: preserve title-only html fallback

* fix: harden html scanner malformed tokens

* fix: close html scanner review gaps

* fix: keep malformed html raw text hidden

* fix: keep html scanner comment content hidden

* fix: skip unsupported html attribute values

* fix: skip raw text from opener end

* fix: drop malformed html tag tails

* fix: preserve trailing slash href links

* fix: close html scanner review gaps

* fix: preserve literal less-than text

* fix: bound html render context nesting

* fix: drop bogus html closing tags

* fix: handle abrupt html comments

* fix: remove dead html scanner branches

* fix: close quoted self-closing html tags

* fix: track anchor text incrementally

* fix: ignore quoted raw text markers

* fix: close title contexts through literal markup

* fix: close anchors through nested contexts

* fix: close nested HTML contexts consistently
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 9, 2026
* fix: harden web fetch html conversion

* fix: consume malformed html tag tails

* fix: consume invalid html tag spans

* fix: preserve html scanner edge cases

* fix: preserve title-only html fallback

* fix: harden html scanner malformed tokens

* fix: close html scanner review gaps

* fix: keep malformed html raw text hidden

* fix: keep html scanner comment content hidden

* fix: skip unsupported html attribute values

* fix: skip raw text from opener end

* fix: drop malformed html tag tails

* fix: preserve trailing slash href links

* fix: close html scanner review gaps

* fix: preserve literal less-than text

* fix: bound html render context nesting

* fix: drop bogus html closing tags

* fix: handle abrupt html comments

* fix: remove dead html scanner branches

* fix: close quoted self-closing html tags

* fix: track anchor text incrementally

* fix: ignore quoted raw text markers

* fix: close title contexts through literal markup

* fix: close anchors through nested contexts

* fix: close nested HTML contexts consistently
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: L status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant