BUIzz and the Missing State Transition

BUIzz is a browser-testing framework built to find policy-enforcement bugs triggered by actions in the browser user interface. This series examines a specific question through BUIzz: what happens when a security policy that works on the initial page must survive a navigation or rendering change initiated outside the page itself? The answer matters because the security of a correctly configured site can depend on behavior controlled by the browser, not by the site's HTML or application code.

The page can be correct—and still become unsafe

Consider a page that contains a link to content under the page's control. The page arrives with a Content Security Policy (CSP) that allows a carefully authorized script, such as one carrying the right nonce, while blocking an inline or otherwise unauthorized script. On the first visit, the browser behaves as expected. The authorized code runs; the code that should be blocked does not.

Now change only the way the link is opened. Instead of a script on the page activating the link, a user drags it to the address bar or chooses a command such as “Open link in split view.” The browser may create a new document, a new pane, or a new browsing context. If that transition loses the policy restriction, code that was blocked on the initial page can run after the interaction. The page's header did not become less careful. The browser's handling of the transition did.

That is the essential shape of the cases BUIzz studies. The paper's motivating Chrome example uses a link that leads to a blob: URL. After the link is dragged to the address bar, a script that should remain blocked executes because the parent CSP is not carried into the resulting context. The paper also describes a Brave case involving a SameSite=Strict cookie. A cross-site request should not include that cookie, yet opening a link in split view causes the cookie to be included. In both examples, the user interaction is not decorative. It changes the security-relevant path through the browser.

This distinction separates a policy-enforcement bug from a website that simply configured its policy badly. A site can make a mistake by allowing an unsafe script source or by omitting a restriction. BUIzz is concerned with a different failure: the site has supplied a policy, the browser has received it, and a browser-owned action causes the browser to apply that policy inconsistently. The same test page can therefore produce a protected result in one state and a weaker result in another.

The consequence is not limited to a surprising display. If a CSP restriction disappears, an attacker who can place script in a vulnerable page may obtain JavaScript execution under the target origin. If a SameSite restriction is bypassed, a cross-site request may carry a cookie that was intended to protect against request-forgery attacks. Similar boundary failures can affect permission to use sensitive browser features, isolation from a popup's opener, transport upgrades to HTTPS, or protection against framing. The specific consequence depends on the policy, but the structural problem is the same: a guarantee was attached to one browser state and failed to follow the user into the next one.

The interaction can also require a real person. The study's exploitation model assumes that an attacker-controlled site may act as a stepping stone and persuade a victim to use a particular browser command or gesture. That condition can make an exploit harder than a vulnerability triggered automatically by loading a page. It does not make the enforcement failure irrelevant. Browser UI features are part of the environment in which sites operate, and a security guarantee that disappears when a user follows an ordinary browser path is a guarantee with a boundary.

A security header is a promise the browser must keep

To see why the boundary matters, start with the ordinary path. A browser requests a page. The server returns a response, often with security-related headers. The browser interprets those headers and enforces the resulting rules while it loads resources, executes code, creates documents, sends requests, and renders content. The website declares the policy, but the browser owns the enforcement step.

That last step is easy to compress into the phrase “the browser blocks it.” In practice, different policies constrain different actions. CSP limits which resources can load or execute and can impose sandbox restrictions. SameSite cookie attributes control when cookies accompany cross-site requests. Permissions Policy controls access to capabilities such as geolocation or the camera. Cross-Origin-Opener-Policy controls whether a page retains an opener relationship with another origin. HSTS requires later connections to use HTTPS. Framing policies and Referrer-Policy govern other parts of the browser's behavior. These are not interchangeable switches. Each one has a distinct protected state and therefore a distinct way in which a transition can weaken it.

CSP provides a particularly clear example because its rules apply not only to the first document but also to content that the document creates or opens. The current W3C CSP Level 3 text explains that documents loaded from local schemes should inherit a copy of the source document's policies. It names srcdoc, blob:, data:, and certain about:blank documents as cases where inheritance prevents a page from escaping restrictions by opening content that it controls. Without that rule, a page could create a new context containing inline script and use the new context to evade a policy that blocks such script in the parent.

The important idea is not that every local-scheme URL is automatically hostile. The important idea is continuity. When a page creates a related document, the browser must decide which policy state crosses the boundary, which origin is used for matching, and which checks apply to the new context. The W3C text describes the inherited policy as a copy or snapshot made when the new document is created. That detail makes the policy a stateful browser obligation rather than a label attached permanently to the original response.

The same reasoning applies beyond CSP. A SameSite=Strict attribute expresses a condition on cookie attachment, not merely a preference stored in the server response. HSTS expresses a condition on the scheme used for a later connection. COOP expresses a condition on the relationship between browsing contexts. When a browser adds a new way to navigate, it must compose that feature with the existing condition. The user-interaction boundary is where that composition becomes visible.

This does not make a policy a complete defense. The W3C document presents CSP as defense in depth: it can reduce the harm caused by content injection, but it does not replace input validation and output encoding. That distinction is useful here. BUIzz does not claim that a browser policy makes a vulnerable site safe in every respect. It tests whether the browser provides the protection the policy is supposed to provide when the page moves through a supported browser path.

The current CSP document is also a Working Draft, not a frozen final Recommendation. That status does not erase the value of its rules or rationale, but it matters when exact language is used to judge behavior. A standards-based finding must keep separate three questions: what the current draft says, what the browser actually did, and what security consequence follows from the difference. BUIzz supplies evidence about the second question and connects it to the first; the interpretation still needs care.

BUIzz asks the missing question

Earlier approaches to browser policy testing generally created policy-bearing documents, visited them, and looked for behavioral differences between browsers. That strategy can find useful inconsistencies, but it begins with a narrow picture of a visit: load the page, run the test, inspect the result. It does not naturally include a keyboard shortcut that reopens a closed tab, a context-menu command that opens a link elsewhere, a drag-and-drop navigation, or a browser-specific split-view operation.

BUIzz changes the question from “Do browsers agree when they load this test page?” to “Does this browser preserve its own policy behavior when a user takes this browser action?” It collects browser UI interactions, applies them to existing test pages, and compares an observable enforcement result before and after the interaction. A JavaScript execution signal can reveal a CSP failure. A request's cookie header can reveal a SameSite failure. A feature request, opener relationship, URL scheme, frame load, or referer header can expose a different policy failure.

That approach keeps the browser, rather than an abstract list of interactions, at the center. Browsers built on the same engine can offer different commands and different rendering paths. A split view, mobile view, sidebar, or workspace is a product feature, but it is also a new composition point for the engine's security rules. BUIzz treats the feature as something that must be exercised, not as an assumption that inherits the engine's guarantees automatically.

The rest of this series follows that shift in perspective. It first makes the policy invariant precise: what should remain protected when a page opens another document or changes context? It then follows the browser UI actions that can exercise the invariant, the testing loop that turns a transition into evidence, and the failure cases that show why the distinction matters. The opening question is therefore narrow but consequential. A security policy is not finished when the server sends its header. It is finished only when the browser preserves the intended restriction through the whole user journey.

flowchart LR R["Server response with policy"] --> I["Initial document: policy enforced"] I --> U["Browser UI interaction outside document"] U --> T["New navigation or rendering context"] T --> O["Observable enforcement outcome"] I -. "BUIzz baseline" .-> C["Pre/post comparison"] O --> C C --> P["Invariant preserved"] C --> B["Candidate policy-enforcement bug"]

References