From 2ac160b4a2b7cd7872a517dbac149476c431e999 Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Fri, 25 Sep 2026 06:06:32 +0000 Subject: [PATCH] feat(ads): let a video unit measure itself, and harden the field that made that risky MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds allow-scripts to the ad.js srcdoc iframe for video and audio fills only, so an in-banner video served through the JSON tag can report playback the way the frame path already does. Roughly 9 video impressions a day were invisible: chosen, rendered, and silent. allow-same-origin is NOT granted and must never be. The two together let a framed document reach frameElement and delete its own sandbox attribute, which is not a sandbox. Without it the creative keeps an opaque origin: it cannot read the publisher's DOM, cookies or storage, and a compromised creative gets its own inert box and nothing else. There is a test asserting the string never appears in a sandbox value. Granting it per-medium rather than to every fill follows the autoplay permission immediately below it: a static banner has nothing to report and still runs nothing at all. The hardening is the precondition. `font_family` was the one advertiser-derived value reaching a CSS context, interpolated raw in four places. esc() is the wrong tool there — inside a diff --git a/tests/ads-font-family-safety.test.ts b/tests/ads-font-family-safety.test.ts new file mode 100644 index 00000000..a0d8db26 --- /dev/null +++ b/tests/ads-font-family-safety.test.ts @@ -0,0 +1,44 @@ +import { describe, expect, it } from "vitest"; +import { DEFAULT_FONT_STACK, safeFontFamily } from "@/lib/ads/creative"; + +describe("safeFontFamily", () => { + it("keeps both stacks that actually ship", () => { + // The only two values in production, across 2,978 creatives. + expect(safeFontFamily("system-ui, -apple-system, Segoe UI, Roboto, sans-serif")).toBe( + "system-ui, -apple-system, Segoe UI, Roboto, sans-serif", + ); + expect(safeFontFamily("system-ui, sans-serif")).toBe("system-ui, sans-serif"); + }); + + it("refuses a value that could close the CSS rule it sits in", () => { + // The whole point: this lands inside a