Cross-Feature Trust Boundary Testing for Security Teams
Use a feature-combination matrix to test shared previews, document privilege crossings, triage vulnerability reports, and verify the complete fix.
Ernest Bursa
Cross-feature trust boundary testing checks whether a capability that is safe in one part of an application becomes unsafe when another feature can reach it. Start with what an attacker controls, trace each bridge into a more privileged context, and test the combinations that make that crossing possible. A feature passing its own security checks is only part of that evidence.
A small security team needs three concrete outputs: a short matrix of feature states, a report showing the capability that became reachable, and a retest that covers the deployed variants. You can begin with one shared artifact and the components that receive messages or render content on its behalf.
A preview can be isolated while its receiver trusts too much
In its October 28 report, Parameter described a ChatGPT chain that combined a shared conversation, a graph and an HTML Preview. According to the researchers, the graph loaded MathLive into the main page. The Preview could then send messages to a listener that accepted keyboard-layout HTML without adequately checking the sender. That rendering path created an unsandboxed frame; an allowed third-party script endpoint supplied a way past CSP.
Parameter demonstrated access to private conversation data through the signed-in session. Its most stable reproduction required opening the share and clicking Preview. It also reported three reproductions in which Preview opened automatically. Parameter says OpenAI confirmed on October 26 that both web frontend versions rejected the reported messages.
Those are researcher-reported findings, not tests we performed. The Hacker News discussion provides the news context. The practical lesson is to test how separate features exchange authority, including the routes that publish or share them.
This task differs from checking whether malicious text can redirect an agent. Prompt injection in a hiring agent’s fetch path concerns how retrieved content influences a tool-using assistant. A browser receiver accepting an unauthorized instruction can fail without persuading a model at all. It also differs from provider tenant isolation, where the question is whether downstream processing separates customers correctly.
Map the point where data becomes authority
A boundary map should identify both the untrusted input and the privileged operation it can influence. “The preview is sandboxed” describes one component. It does not answer what the surrounding application will do when that preview sends a message.
Draw the path in plain language:
- Someone outside the victim’s account controls a shared artifact.
- Opening it loads a component in an authenticated page.
- Another component accepts an instruction from the artifact.
- The instruction influences rendering, a request or an account action.
For each arrow, name the receiver and its reason for accepting the input. Does it check an exact origin? A particular window? A message type? An authorization decision on the server? If the answer is merely that the message has the expected shape, you have identified an assumption to examine.
MDN’s guidance on postMessage calls for checking the sender’s identity and validating received data. It also recommends an exact target origin when sending messages. A recognized message format does not establish permission to use the receiver’s capabilities.
Keep browser and server authority separate in the map. A server may correctly authorize a request as the signed-in user while attacker-controlled code has gained the ability to issue that request. The investigation then needs to explain how that code entered the authenticated context.
Build a small feature-combination matrix
Test the smallest set of combinations that can establish where the boundary changes. Begin with each component alone, then combine them. Include the route that another person actually uses to open the artifact.
The following is an illustrative planning matrix for an application with shared previews. It is not a record of tests against ChatGPT or Kit.
| Test state | Question | Evidence to retain |
|---|---|---|
| Shared artifact, preview disabled | Does viewing the artifact load a privileged receiver? | Loaded components and receiver registration |
| Preview enabled, companion feature absent | Can the preview reach a receiver on its own? | Sender context and observed rejection or handling |
| Companion feature and preview enabled | Does their combination change the accepted message path? | Receiver decision and resulting capability |
| Same combination through a public share | Does sharing preserve the components needed for the crossing? | Route, account state and exact interaction sequence |
| Same combination after a hard reload | Does initialization order change the result? | Timing, load order and repeatability |
| Same combination across deployed variants | Do all active versions enforce the same boundary? | Version identifier and result for each variant |
Record expected behavior before running a row. For example: “The parent rejects a settings message from this preview because the sender has no permission to change that setting.” A failed exploit attempt alone is ambiguous. The receiver might have rejected it, or the receiver might never have loaded.
Use authorized test accounts and benign markers. To investigate a private-data capability, create a test record containing an unmistakable synthetic value. You need enough evidence to establish the crossing; collecting real users’ records adds exposure without improving the explanation.
Vary timing when components initialize independently. Record whether an action works only after another feature loads, whether a reload changes the result, and whether the normal interface requires an extra click. These prerequisites belong in the report because they affect reproducibility and the conditions under which someone could encounter the issue.
Give triage a capability, not just an alert
A useful report establishes what became possible in the affected context. A screenshot of an alert can help establish where JavaScript ran. It leaves unanswered which data or operations that execution could reach.
Give another engineer enough detail to reproduce the result:
- Attacker control: the artifact, field, file or message the reporter can supply.
- Victim prerequisites: account state, role, enabled features and required interactions.
- Boundary crossed: the sender context, receiver and operation the receiver accepted.
- Minimal reproduction: the exact route and sequence, using synthetic test data.
- Expected and observed behavior: what should have been denied and what happened instead.
- Demonstrated impact: the specific private test record or restricted action reached.
- Limits: inconsistent timing, untested roles, unavailable variants and hypothetical extensions.
Separate a demonstrated read from a proposed write. If the proof retrieves a private synthetic record, report that confidentiality impact directly. If another account action appears reachable but has not been tested, label it as a hypothesis. Broad language such as “full account takeover” should not replace the concrete evidence the team needs to assess scope.
When a report cannot be reproduced, identify the missing condition before dismissing it. A companion feature, an alternate frontend version or a second interaction may explain the difference. Ask for that detail explicitly, then add it to the matrix so the next reproduction starts from the same state.
Verify the receiver repair across the whole path
Fix verification should establish why the original crossing now fails. A blocked downstream script can stop a particular demonstration while leaving unauthorized messages able to influence trusted rendering.
Inspect the receiver’s decision and retest the path from the artifact. Can the untrusted sender still change the setting? Can its data still reach an HTML sink? Does dynamically created content retain the intended restrictions? Which control rejects the operation, and can the test observe that rejection?
The OWASP Web Security Testing Guide’s web messaging guidance covers origin checks and input handling. Even input from a permitted origin still needs appropriate validation. Treat origin, window identity, message structure and allowed operation as distinct questions.
Use the original matrix for the retest, then add nearby variants justified by the affected code. That might include an alternate sharing route, another component using the same receiver, or an older frontend still serving traffic. Avoid turning every report into an unlimited audit; follow the shared mechanism and document where the review stops.
Check legitimate behavior too. An authorized component should still complete its intended operation after the unauthorized sender is rejected. Otherwise, a repair that disables the feature entirely may pass a security reproduction while breaking the workflow users need.
Keep resolution and verification distinct
Record the remediation and the evidence that confirms it as separate steps. A deployed change establishes that someone shipped a fix. Verification establishes what was retested, on which version, and with what result.
Kit’s Security workflow includes separate report states for resolved and fix verified. That distinction gives the team a place to track the handoff. It does not run the browser matrix or prove a boundary holds; the report still needs the reproduction, version details and retest evidence.
Start this week with one public or shareable artifact. List the privileged components it can contact, choose one state-changing receiver, and test the artifact alone and in combination with the feature that loads that receiver. The result should tell you where permission is checked and give the next engineer enough evidence to verify the same boundary.
Related articles
Try Kit for 30 days.
Hiring, security reports, and training in one account, for teams where none of it is a full-time job. Free for 30 days, card required. Cancel before it ends and you pay nothing.
Get started free