Harden runner security, accessibility, and release checks#9
Merged
Conversation
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.
Summary
Harden the audited runtime, browser, accessibility, generated-asset, and release boundaries without changing the example catalog or existing routes.
The audit reproduced a Dynamic Worker containment bypass where submitted code could append directly to
sys.stdout.partsand return 200,000 bytes despite the 64 KiB limit. It also found an unreleased ASGI response buffer, missing status observability for bridge-level413s, permissive Turnstile result handling, stale browser-run races, weak dark-mode contrast, corrupt social-card acceptance, error-page canonical leakage, and dependency drift in CI.What changed
413.Cache-Control: no-storeon runner POST responses.hostnameand the fixedrun-exampleaction; retry transient CDN failures instead of caching a rejected loader promise.#code=fragments before decoding.og:urlmetadata and emitnoindexon error pages.uv sync --locked --all-groups, add an npm lock, pin Wrangler 4.110.0, and audit high-severity Node dependencies in CI.Verification
make verify— 220 tests, 109 executable examples, browser contracts, SEO/cache lint, quality gates, Ruff, and generated-drift checks passedscripts/format_examples.py --checkmake verify-python-version VERSION=3.13git diff --checknpm audit --audit-level=high— 0 vulnerabilitiessys.stdout.parts.append("X" * 200000)returned HTTP413with a bounded 9,527-byte HTML responseBrowser coverage now exercises concurrent response ordering, native Reset, Unicode sharing, oversized fragments, transient Turnstile CDN retry and token/action propagation, pending editor CDN requests, search failure announcements, live light/dark theme changes, focus indicators, and contrast measurement.
Visual evidence
Reproduce from the corresponding revision with:
Base:
46000c7; head:730d0e3; viewport: 1200×900, dark color scheme.make browser-layout-testindependently calculates the rendered contrast and fails below 4.5:1.Risk
This touches shared Worker response handling, the ASGI bridge, browser runner state, and release workflows. Risk is constrained with defense-in-depth output caps, explicit status propagation, behavioral browser tests, adversarial unit tests, exact dependency locks, and a full verification pass. Pillow is added only to the development group for real JPEG decoding.
The repository still cannot prove the external Cloudflare account-level WAF/rate-limit rule is active; that remains an operator-side deployment control documented in
docs/turnstile-runner-protection-spec.md.