← Commit history

web-control: document wiki_fetch (signed-in reads, and why the origin lock parses instead of prefix-matching)

John Lauer ·220cb9d68a ·2mo ago ·parent 774d120
1 file changed +39
docs/web-control.md+39
@@ -174,6 +174,45 @@ single-shot write_file  ->  HTTP 413 "length limit exceeded" write_file_chunk        ->  4 chunks, 0.9s, 3,921,735 bytes, sha256 verified ``` +## Private wiki pages: `wiki_fetch` (ab 2.0.74+)++A web page can already read anything **public** on the wiki - it just fetches it. What it+cannot do is read a page that is **private to the user**, because the browser holds no Adom+session for `wiki.adom.inc`. ab does. `wiki_fetch` exposes that one capability:++```+wiki_fetch {url}+  -> {httpStatus, url, contentType, size, base64}+```++This is not hypothetical. Three of the ten parts in the demo's picker were private, so the+browser got a 404 and the card reported a mystery "blocked" - the page had no way to tell+"this file does not exist" from "this file is not yours to read anonymously".++**Fetch anonymously first, and fall back to this only when that fails.** The demo does exactly+that. Anonymous is the default so the user's credential is spent on the reads that genuinely+need it, rather than on every read by habit.++**The origin lock is the entire security story.** Without it this verb is a general credentialed+proxy: any approved page could have ab attach the user's bearer token to a request at an+attacker's host. So the URL is **parsed**, and the host must be exactly `wiki.adom.inc` over+https.++Parsing rather than prefix-matching is deliberate and load-bearing:++```+https://[email protected]/steal+```++That string *begins with* `https://wiki.adom.inc`, yet its host is `evil.com`. A `startsWith`+guard hands the user's token straight to the attacker; `Url::parse` resolves the userinfo+correctly and refuses it. `wiki_fetch_url_tests` covers that case along with subdomain+lookalikes (`wiki.adom.inc.evil.com`), plain http, and `file://`.++The token itself never leaves ab - the caller receives bytes, never the credential. Web callers+reach this through the ordinary consent gate, so a human approves it with the URL named in the+prompt.+ ## The wiki render surface  The wiki renders a page's readme as HTML inside a sandboxed iframe served from