the cookie-free claim gets a gate: four served trees, one allow-list each - #3920
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a repository gate to protect the “cookie-free” property of the served web trees by mechanically scanning markup/script/style sources for document.cookie usage and for off-site resource loads not present in a per-tree host allow-list. This is implemented as a reusable gate in dastest/review_gate.das, then wired into four served-tree checklists (site/, site-dasllama/, doc/, web/).
Changes:
- Introduces
gate_web_third_partyplus URL extractors (html_resource_urls,script_urls,css_urls,url_host) indastest/review_gate.das. - Adds/extends tests in
dastest/tests/test_review_gate.dasfor the new scanners and edge cases. - Adds new per-folder
REVIEW.md/REVIEW.dasgates and allow-lists forweb/anddoc/, and extendssite// addssite-dasllama/gating.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| web/REVIEW.md | New checklist rules tying served web trees to the cookie/host gate and allow-list disclosure. |
| web/REVIEW.das | New gate runner wiring web/ deployed roots into gate_web_third_party. |
| web/LAWS.md | New intent-provenance ledger for the new web/ rule documents. |
| site/REVIEW.md | Extends site checklist with weakening/disclosure rules for the cookie/host gate. |
| site/REVIEW.das | Adds ALLOWED_HOSTS + SKIP_DIRS and runs gate_web_third_party over site/. |
| site/LAWS.md | Appends rulings provenance related to adopting the new gate rules. |
| site-dasllama/REVIEW.md | Extends checklist with weakening/disclosure rules for the cookie/host gate. |
| site-dasllama/REVIEW.das | New gate runner for site-dasllama/ using gate_web_third_party. |
| site-dasllama/LAWS.md | New intent-provenance ledger for the new site-dasllama/ rule documents. |
| doc/REVIEW.md | New checklist binding doc inputs to the cookie/host gate + allow-list disclosure. |
| doc/REVIEW.das | New gate runner scanning doc/source plus conf.py absolute URLs against allow-list. |
| doc/LAWS.md | New intent-provenance ledger for the new doc/ rule documents. |
| dastest/tests/test_review_gate.das | Adds tests for URL host parsing and the new HTML/CSS/script scanners and gate behavior. |
| dastest/review_gate.das | Implements the new web cookie/third-party host gate and supporting URL scanners/parsers. |
| dastest/README.md | Updates documentation to include the new gate and helper functions. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
borisbat
force-pushed
the
bbatkin/web-third-party-gates
branch
from
September 1, 2026 19:44
dd8c8d4 to
d26e0d3
Compare
borisbat
force-pushed
the
bbatkin/web-third-party-gates
branch
from
September 1, 2026 19:52
d26e0d3 to
afe8a0f
Compare
borisbat
force-pushed
the
bbatkin/web-third-party-gates
branch
from
September 1, 2026 20:06
afe8a0f to
95968a2
Compare
…each The audit found daslang.io and dasllama.io set no cookies, and nothing stopped the next embed from walking that back. gate_web_third_party reads every markup, script and stylesheet file under a served tree for document.cookie and for a host its allow-list does not name - markup contributes its resource tags and inline script bodies, script text its URL literals, a stylesheet its @import and url() addresses. A link the visitor must click is not a load, so <a> and <meta> are left out; a data-* attribute of a resource tag is one, which is how a beacon endpoint is caught rather than only its src. Four gates, because the served set is wider than the two site folders: site/ and site-dasllama/ carry the pages, doc/ adds source/conf.py (Sphinx writes html_css_files and html_js_files into every page head, so that list is a load no template shows), and web/ covers the two playground trees the deploy stages into site/ - both gitignored where they land, so no site-rooted gate sees them in a fresh checkout - plus the canvas shell daspkg release --web wraps user programs in. The web/ list is empty: those trees fetch nothing off-site. Each allow-list entry is negative-controlled at a real call site, so none is dead weight. Review rounds found six parsing bypasses, each reproduced by a test that fails before its fix: single-quoted URLs cut in half by the double-quote-only comment strip, unquoted attribute values, multi-address srcset, protocol-relative URLs in template literals, uppercase schemes and closing tags, and bracketed IPv6 hosts. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UPY7onu9xGAToiEMWkLBtg
borisbat
force-pushed
the
bbatkin/web-third-party-gates
branch
from
September 1, 2026 20:12
95968a2 to
0524cc2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An audit of daslang.io and dasllama.io found that neither site sets a cookie, and that
nothing stopped the next embed from walking that back. This adds the gate. Sixteen live
pages were loaded in a fresh browser context each: no cookie jar entry, no
Set-Cookieonany response including third-party subresources, no service worker, no IndexedDB. What the
sites do store is six functional localStorage keys, none of which leaves the browser.
gate_web_third_partyreads every markup, script and stylesheet file under a served treefor
document.cookieand for a host its allow-list does not name. Markup contributes itsresource tags and inline script bodies, script text its URL literals, a stylesheet its
@importandurl(...)addresses. A link the visitor must click is not a load, soaandmetaare left out; adata-*attribute of a resource tag is one, which is how a beaconendpoint is caught rather than only its
src. Schemes, host names and tag names are readcase-insensitively, attribute values quoted or bare, and a multi-address
srcsetsplits.Four gates, because the served set is wider than the two site folders.
site/andsite-dasllama/carry the pages.doc/addssource/conf.py: Sphinx writeshtml_css_filesandhtml_js_filesinto every page head, so that list is a load notemplate shows.
web/covers the two playground trees the deploy stages intosite/-both are gitignored where they land, so no site-rooted gate would see them in a fresh
checkout - plus the canvas shell
daspkg release --webwraps user programs in. Theweb/allow-list is empty: those trees fetch nothing off-site.
Where to look:
gate_web_third_partyand the scanners under it indastest/review_gate.das;the allow-list in each of the four
REVIEW.dasfiles.Validation, claims, ledger
Validation
skipped, no C++ changed). No full tier: the diff adds no engine, macro, JIT or AOT
surface. CI re-proves the rest.
fires -
examples.js:15,daspkg.js:6,github-star.js:50,index.html:12forsite/,source/conf.py:173and:182fordoc/. No entry is dead weight.scripttag and adocument.cookiewrite inindex.html; ascriptinside an RST.. raw:: htmlblock;@import url("https://fonts.googleapis.com/...")indoc/source/_static/custom.css; a pixel URL and a cookie write inweb/examples/ui/src/main.js.the reviewed commit before its fix: unquoted attribute values, multi-address
srcset,protocol-relative URLs in template literals, uppercase URL schemes, and an uppercase
</SCRIPT>closing tag.utils/internal/review-md/all.das), dastest 43/43.Claims - stated, not tested
pages across both sites, fresh context each, cookies and storage read after
networkidleplus a forced DocSearch query. Nothing in CI re-runs it. A break would show as a cookie
appearing on a page whose sources the gate still passes - possible only through a host
already on an allow-list, or through the doc tree's generated output, which is gitignored
and therefore outside every gate.
web/examples/ui/samplesis a gate root that reads nothing today: the tree holds.dasand
.jsononly, and its three.mdfiles are rule documents the walker skips. It islisted so the first
.html,.jsor.csssample added there is gated on arrival, notbecause it closes a live hole.
Not done
site/doc(generated Sphinx output) andsite/tests(the Playwright harness) are notwalked. The first is gitignored, so it does not exist in a fresh checkout; its inputs are
gated at
doc/sourceinstead.document.cookiecheck reads markup as text, so a blog post that quotes the API in acode sample would be a finding. None does today.
is the only thing standing behind that decision.
.das.assets.jsonsidecar is not scanned. The two that exist carry relative paths only.site/REVIEW.md'sduplicated receipt tail and undefined "editor content",
site-dasllama/REVIEW.md'sthree-file page census and two rules carrying two triggers each - plus six automation
candidates. All are reported to the author rather than rewritten here.
🤖 Generated with Claude Code