Follow-up from the review of #2286. Not a blocker for that PR — the branded host has landed and the loader is scoped — but the hardening gap it identified is still open and now has no home.
What is true today
assistant.js injects a third-party script onto every published page with no integrity or origin controls:
// assistant.js:16-20
var script = document.createElement('script');
script.src = WIDGET_SRC; // https://docs-assistant.celo.org/widget.js
script.dataset.apiUrl = 'https://docs-assistant.celo.org/api/chat';
script.referrerPolicy = 'strict-origin';
- No
integrity attribute and no crossOrigin — verified: grep -c "integrity\|crossOrigin" assistant.js returns 0.
- No CSP anywhere in the repo to fall back on — there is no
vercel.json, no _headers, no middleware, and docs.json has no headers key (verified by loading docs.json and checking for the key).
Per AGENTS.md §1, any .js under the content root runs on every published page with full same-origin DOM access — including the pages that print contract addresses and RPC endpoints.
Impact
Whoever controls docs-assistant.celo.org can execute arbitrary JS on every docs page. That is currently us, which is why this is a follow-up and not a blocker. The residual risk is a compromise or misconfiguration of that host silently becoming a compromise of the docs, with no second control to catch it. A reader copying a contract address has no way to tell.
Why this is not simply "add SRI"
widget.js is first-party and expected to change on its own deploy cadence. An integrity hash pins one build, so adding SRI naively breaks the widget on the next widget deploy. Options worth weighing:
- Pin SRI and add a release step that updates the hash in
assistant.js (couples two repos, but fails closed).
- Add
crossOrigin="anonymous" now — cheap, no downside, and a prerequisite for SRI later.
- Ask Mintlify whether response headers (CSP with
script-src) are configurable on the current plan; if so, an allowlist for docs-assistant.celo.org is stronger than SRI and does not break on deploy.
Acceptance criteria
Refs #2250, #2286.
Follow-up from the review of #2286. Not a blocker for that PR — the branded host has landed and the loader is scoped — but the hardening gap it identified is still open and now has no home.
What is true today
assistant.jsinjects a third-party script onto every published page with no integrity or origin controls:integrityattribute and nocrossOrigin— verified:grep -c "integrity\|crossOrigin" assistant.jsreturns0.vercel.json, no_headers, no middleware, anddocs.jsonhas noheaderskey (verified by loadingdocs.jsonand checking for the key).Per AGENTS.md §1, any
.jsunder the content root runs on every published page with full same-origin DOM access — including the pages that print contract addresses and RPC endpoints.Impact
Whoever controls
docs-assistant.celo.orgcan execute arbitrary JS on every docs page. That is currently us, which is why this is a follow-up and not a blocker. The residual risk is a compromise or misconfiguration of that host silently becoming a compromise of the docs, with no second control to catch it. A reader copying a contract address has no way to tell.Why this is not simply "add SRI"
widget.jsis first-party and expected to change on its own deploy cadence. Anintegrityhash pins one build, so adding SRI naively breaks the widget on the next widget deploy. Options worth weighing:assistant.js(couples two repos, but fails closed).crossOrigin="anonymous"now — cheap, no downside, and a prerequisite for SRI later.script-src) are configurable on the current plan; if so, an allowlist fordocs-assistant.celo.orgis stronger than SRI and does not break on deploy.Acceptance criteria
crossOriginset on the injected script unless there is a stated reason not toscript-srcrestricted to the known hostsRefs #2250, #2286.