{"slug": "your-agent-can-t-safely-read-a-web-page-it-hasn-t-read-yet", "title": "Your agent can't safely read a web page it hasn't read yet", "summary": "TrustSource launched SafeFetch, a server-side URL scanner that detects prompt injections in web pages before an AI agent reads them. The tool returns a verdict of SAFE, REVIEW, or BLOCK based on concealed text and risk scoring, preventing attacks that execute when malicious content enters a model's context window.", "body_md": "\n\n```\nGET https://api.trustsource.cc/safefetch?url=<percent-encoded-url>\n```\n\n`SAFE`\n\n/ `REVIEW`\n\n/ `BLOCK`\n\nprompt-injection verdict.`BLOCK`\n\n→ discard the content. `REVIEW`\n\n→ use as data, never as instructions. `SAFE`\n\n→ use normally.`402`\n\nwith a `PAYMENT-REQUIRED`\n\nheader. Sign the EIP-3009 authorization it describes and repeat the same request with an `X-PAYMENT`\n\nheader.That's everything you need to call it. The rest explains how it decides.\n\nYou want to know whether a page is safe **before** your model reads it. But the usual way to find out is to ask the model — which means feeding it the page. If the page contains a prompt injection, you've already lost. The attack runs the moment the text enters the context window.\n\n`fetch()`\n\ngives you no verdict. It hands your agent a string and hopes for the best.\n\nSafeFetch fetches the URL server-side, separates what a human would actually see from what's concealed in the markup, scans both, and returns clean text plus a verdict:\n\n```\n{\n  \"url\": \"https://example.com/\",\n  \"verdict\": \"BLOCK\",\n  \"risk\": 0.95,\n  \"reasons\": [\"instruction override concealed in hidden content (matched in hidden content)\"],\n  \"injection\": {\n    \"detected\": true,\n    \"techniques\": [\"instruction_override\"],\n    \"findings\": [\n      { \"technique\": \"instruction_override\", \"placement\": \"hidden\", \"severity\": 0.95, \"weight\": 0.95 }\n    ]\n  },\n  \"content\": { \"text\": \"…sanitized page text…\", \"truncated\": false }\n}\n```\n\nYour agent branches on one field instead of reasoning about raw HTML.\n\n**SAFE** means nothing concealed and aggregate risk under 0.25. **REVIEW** means risk between 0.25 and 0.7, or a content type that couldn't be scanned, or a low-trust host. **BLOCK** means a critical technique found in hidden or comment placement, or risk ≥ 0.7.\n\nThis is the part that makes it usable in production.\n\nA blog post *about* prompt injection contains the exact phrases an injection scanner looks for. A naive keyword filter flags every security article on the internet and becomes noise you learn to ignore.\n\nSafeFetch weights each finding by **where** it was found — `hidden`\n\n1.0, `comment`\n\n0.95, `accessibility`\n\n0.6, `metadata`\n\n0.55, `script`\n\n0.5, `visible`\n\n0.2 — and caps visible-text hits in aggregate. So \"ignore all previous instructions\" printed in an article body scores low, while the same string in a `display:none`\n\ndiv scores high.\n\nConcealment *is* the signal. Nobody hides text from humans for a benign reason.\n\nEleven techniques: `instruction_override`\n\n, `system_prompt_exfil`\n\n, `data_exfiltration`\n\n, `delimiter_spoof`\n\n, `encoded_payload`\n\n, `tool_call_bait`\n\n, `role_hijack`\n\n, `homoglyph_obfuscation`\n\n, `unicode_tag_smuggling`\n\n, `invisible_unicode`\n\n, `bidi_override`\n\n.\n\nThat covers instructions buried in `display:none`\n\nelements, HTML comments and `alt`\n\nattributes; invisible Unicode-Tag (U+E0000) and zero-width smuggling; homoglyph and base64-encoded payloads; ChatML / `[INST]`\n\ndelimiter spoofing; markdown-image exfiltration; and tool-call bait. Payloads split across several hidden elements are reassembled and scanned as one string, so chunking the attack doesn't evade it.\n\nThe 402 response names the scheme (`exact`\n\n), the network (`eip155:8453`\n\n— Base mainnet), the amount (`10000`\n\natomic units, i.e. $0.01 USDC), the USDC contract, and the address to pay.\n\nThe agent signs an EIP-3009 `transferWithAuthorization`\n\nfor that exact amount, base64-encodes it, and repeats the identical request with an `X-PAYMENT`\n\nheader. The facilitator settles on-chain and the endpoint returns `200`\n\n.\n\nSame URL twice, one extra header, one signature. No session, no nonce to track, and an abandoned 402 costs nothing. Any x402-aware HTTP client handles this for you.\n\n`injection.findings`\n\nare defanged for display. They're evidence, not instructions.One successful injection against an agent with tools, a wallet, or memory is worth considerably more than $0.01 to an attacker.\n\nSafeFetch is one of seven verification endpoints at [trustsource.cc](https://trustsource.cc) — the others cover URL safety verdicts, email spoofability, domain trust, TLS certs, security headers, and AI-crawler policy.", "url": "https://wpnews.pro/news/your-agent-can-t-safely-read-a-web-page-it-hasn-t-read-yet", "canonical_source": "https://dev.to/surfether/your-agent-cant-safely-read-a-web-page-it-hasnt-read-yet-48lg", "published_at": "2026-07-28 10:01:27+00:00", "updated_at": "2026-07-28 10:36:30.204962+00:00", "lang": "en", "topics": ["ai-safety", "ai-agents", "ai-infrastructure", "ai-tools"], "entities": ["TrustSource", "SafeFetch", "Base", "USDC"], "alternates": {"html": "https://wpnews.pro/news/your-agent-can-t-safely-read-a-web-page-it-hasn-t-read-yet", "markdown": "https://wpnews.pro/news/your-agent-can-t-safely-read-a-web-page-it-hasn-t-read-yet.md", "text": "https://wpnews.pro/news/your-agent-can-t-safely-read-a-web-page-it-hasn-t-read-yet.txt", "jsonld": "https://wpnews.pro/news/your-agent-can-t-safely-read-a-web-page-it-hasn-t-read-yet.jsonld"}}