---
id: 567552a1-389b-4856-9e3e-1b320d5f1095
title: Pages artifact download policy is invalid (two splats), allowing active HTML/SVG
state: closed
labels:
- kind:security
assignees: []
milestone: null
created: 2026-10-27T18:39:46.325820585Z
updated: 2026-10-27T19:53:10.416654271Z
---
## Problem

The Pages artifact download policy is invalid: Cloudflare `_headers` allows only one `*` wildcard per rule, but `HEADERS_FILE` emits `/releases/*/*`. Wrangler reports it invalid and skips it, so release artifacts are served as active same-origin HTML/SVG instead of downloads. This means f0rge #97 is still open on Pages even though `hu13 serve` is fixed.

## Verified reproduction

`wrangler pages dev` 4.154.0 over a dist with `.forge/releases/out/v1/evil.html` and `evil.svg`:

```
Found 1 invalid header rule:
  Only one wildcard is allowed per rule. Use a named placeholder (e.g. :project) instead. Skipping /releases/*/*.
  at dist/_headers:7 | /releases/*/*
```

Then:

```
GET /releases/v1/evil.svg      -> 200 image/svg+xml, no Content-Disposition
GET /releases/v1/evil.html     -> 308 Location: /releases/v1/evil
GET /releases/v1/evil          -> 200 text/html, no Content-Disposition
```

Both artifact bodies are script-bearing and execute in the inbox origin. `src/build.rs:1157`, `docs/cloudflare.md:94`, and `.forge/wiki/deploy:69` all claim the artifact download policy exists.

## Fix candidate

Use `/releases/:version/*` (one splat plus a placeholder). Verified with Wrangler: it parses as valid, applies `Content-Disposition: attachment` to extensionless artifact URLs and artifact directory indexes, and leaves `/releases/v1` release pages inline. Add a real Wrangler/Pages header test instead of only checking the string.
