Skip to content

Reject disallowed first-party proxy targets before signing - #1077

Open
ChristianPavilonis wants to merge 2 commits into
mainfrom
first-party-sign-allowlist
Open

Reject disallowed first-party proxy targets before signing#1077
ChristianPavilonis wants to merge 2 commits into
mainfrom
first-party-sign-allowlist

Conversation

@ChristianPavilonis

Copy link
Copy Markdown
Collaborator

Summary

  • Reject valid HTTP and HTTPS targets at /first-party/sign when their parsed host does not match proxy.allowed_domains, before expiry or signature work begins.
  • Keep dynamic images and iframes blocked after a signing 403, while preserving the existing direct-load fallback for network errors, malformed responses, and other HTTP failures.
  • Add GET and POST regression coverage and update operator documentation to describe signing, initial-fetch, redirect, and open-mode behavior.

Changes

File Change
crates/trusted-server-core/src/proxy.rs Reuses one parsed-host policy for signing and fetching, logs rejected hosts, and adds the fourteen-case GET and POST matrix.
crates/trusted-server-core/src/error.rs Generalizes the allowlist violation wording beyond redirects.
crates/trusted-server-core/src/settings.rs Documents the full allowlist policy and updates the open-mode log message.
crates/trusted-server-js/lib/src/integrations/creative/proxy_sign.ts Returns explicit signed, fallback, and blocked outcomes.
crates/trusted-server-js/lib/src/integrations/creative/dynamic_src_guard.ts Suppresses native resource assignment for blocked outcomes.
crates/trusted-server-js/lib/test/integrations/creative/proxy_sign.test.ts Covers successful signing, policy rejection, malformed responses, and non-policy fallback.
crates/trusted-server-js/lib/test/integrations/creative/image.test.ts Verifies a blocked assignment preserves the previous image source.
crates/trusted-server-js/lib/test/integrations/creative/iframe.test.ts Verifies a blocked iframe source is not applied directly.
docs/guide/api-reference.md Documents signing-time enforcement, the 403 response, and the actual { href, base } response shape.
docs/guide/configuration.md Describes allowlist matching across signing, initial fetches, and redirects.
docs/guide/first-party-proxy.md Documents signing policy, browser rejection behavior, and open mode.
trusted-server.example.toml Updates the allowed_domains comment to cover signing and fetching.
CHANGELOG.md Records the security fix under Unreleased.
docs/superpowers/specs/2026-08-26-first-party-sign-allowlist-enforcement-design.md Adds the approved behavior and completion criteria.
docs/superpowers/plans/2026-08-26-first-party-sign-allowlist-enforcement.md Adds the approved implementation and validation checklist.

Scope

The change spans core signing policy, the creative browser runtime, regression tests, and maintained documentation because returning 403 earlier would otherwise make the browser fall back to the rejected raw URL. It does not change adapters, routes, authentication, CORS, DNS or IP policy, token format, expiry, dependencies, or the configuration schema.

Closes

Closes #1035

Test plan

  • cargo test-fastly && cargo test-axum
  • cargo clippy-fastly && cargo clippy-axum
  • cargo fmt --all -- --check
  • JS tests: cd crates/trusted-server-js/lib && npx vitest run
  • JS format: cd crates/trusted-server-js/lib && npm run format
  • Docs format: cd docs && npm run format
  • WASM build: cargo build --package trusted-server-adapter-fastly --release --target wasm32-wasip1
  • Manual testing via fastly compute serve
  • Other: cargo test-cloudflare, cargo test-spin, parity tests, all target-specific Clippy gates, JavaScript build, documentation lint/build, and git diff --check

Checklist

  • Changes follow CLAUDE.md conventions
  • No unwrap() in production code; expect("should ...") is used where applicable
  • Uses logging macros, not println!
  • New code has tests
  • No secrets or credentials committed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enforce proxy.allowed_domains when minting signed URLs at /first-party/sign

1 participant