WEB / WEB-11.04
CSP, sandbox and secure context
Separate browser policy boundaries for connections, execution, embedding and environments.
1. Core · Mechanism
Read every scenario without motion
Allowed GET
- Document policy ready
Atlas selects a same-origin read-only GET for /notes/title. Enforced connect-src self matches, but the local gate has not yet run and the endpoint has no request. This scene does not execute redirect or credential decisions.
- Browser
- Policy ready; no GET
- Notes endpoint
- No request
- Local CSP gate
connect-src self/none and disposition were read together; whether the ordinary GET proceeds was decided locally.
- Browser
- CSP allow
- Notes endpoint
- No request
- GET arrived at endpoint
The ordinary read-only GET arrived at the endpoint; this arrival is request receipt, not a user authorization decision.
- Browser
- CSP allow
- Notes endpoint
- GET received; policy pending
- Server reads its own gate
The synthetic server accepted this previously permitted read-only operation; browser CSP did not replace server policy.
- Browser
- CSP allow
- Notes endpoint
- Read-only response ready
- Response at browser
The ordinary response arrived at the browser; any report-only diagnostic is held in separate local state.
- Browser
- Response received; no violation
- Notes endpoint
- Read-only response ready
- Read the result
The browser accepted the response for read-only presentation; no actual report delivery or DOM execution occurs here.
- Browser
- Read-only result; authz separate
- Notes endpoint
- Read-only response ready
Connection deny
- Document policy ready
Atlas selects the same /notes/title GET, but the enforced source list is connect-src none. The local gate has not yet run and the endpoint has received no request; denial occurs at the later browser-local decision.
- Browser
- Policy ready; no GET
- Notes endpoint
- No request
- Local CSP gate
connect-src self/none and disposition were read together; whether the ordinary GET proceeds was decided locally.
- Browser
- CSP deny; no send
- Notes endpoint
- No request
- Local diagnostic
The enforcement violation was recorded locally; no ordinary GET arrival occurred at the endpoint.
- Browser
- Violation recorded; no GET
- Notes endpoint
- No request
- Denial completed
The expected result is denial before the network; endpoint state remains No request throughout this branch.
- Browser
- Denied; no server receipt
- Notes endpoint
- No request
Report-only
- Document policy ready
Atlas selects the same /notes/title GET; connect-src none now has report disposition. The later local check records a violation without blocking this request. Neither endpoint receipt nor report delivery has occurred yet.
- Browser
- Policy ready; no GET
- Notes endpoint
- No request
- Local CSP gate
connect-src self/none and disposition were read together; whether the ordinary GET proceeds was decided locally.
- Browser
- CSP allow
- Notes endpoint
- No request
- GET arrived at endpoint
The ordinary read-only GET arrived at the endpoint; this arrival is request receipt, not a user authorization decision.
- Browser
- CSP allow
- Notes endpoint
- GET received; policy pending
- Server reads its own gate
The synthetic server accepted this previously permitted read-only operation; browser CSP did not replace server policy.
- Browser
- CSP allow
- Notes endpoint
- Read-only response ready
- Response at browser
The ordinary response arrived at the browser; any report-only diagnostic is held in separate local state.
- Browser
- Response received; violation recorded
- Notes endpoint
- Read-only response ready
- Read the result
Despite the report-only violation, the GET reached the endpoint and its read-only response returned to the browser. A local diagnostic is not proof of delivery to a reporting endpoint; server authorization and DOM execution cannot be inferred.
- Browser
- Read-only result; authz separate
- Notes endpoint
- Read-only response ready
HTTP ancestor
- A separate context question
This branch considers an environment prerequisite for a secure-context feature, not ordinary fetch.
- Browser
- HTTPS frame; gate pending
- Notes endpoint
- No request
- Read creation context
The HTTPS frame is inside a public HTTP parent; the child URL scheme alone is insufficient evidence.
- Browser
- Top creation is public HTTP
- Notes endpoint
- No request
- Context denial
The declared ordinary environment is not secure; no API permission is granted and no endpoint request is shown.
- Browser
- Secure context false
- Notes endpoint
- No request
- Boundary kept separate
Origin, sandbox flags and server policy have to be read independently of this context result.
- Browser
- Context denied; fetch separate
- Notes endpoint
- No request
ACTORS · STATE · DATA FLOW
Which operation consults which policy?
The Atlas Notes document constrains its script sources and ordinary connection destinations. script-src concerns script execution sources, while connect-src concerns destinations used by script interfaces. Inclusion in a source list does not grant API account or tenant access. The browser permitting a connection to a URL and the server allowing that user to read a note are separate decisions; an ordinary request has to satisfy both.
frame-src states which child document URLs a parent may load; frame-ancestors states which ancestors may embed the loaded resource. The second decision belongs to the child response policy and evaluates the ancestor chain. frame-ancestors does not fall back to default-src and is not applied from meta. Adding the preview host to the parent policy therefore does not automatically mean that the preview response accepts that parent.
Sandbox is not an origin equality
An iframe sandbox restricts script, form, navigation and origin behavior through flags. In this example an empty token set blocks script execution and form submission and makes the origin opaque. allow-scripts relaxes the script restriction alone; it does not restore the ordinary origin. allow-same-origin relaxes a separate origin flag and does not make a cross-origin document same-origin with its parent. An unchanged URL does not imply unchanged effective origin or capabilities.
CSP sandbox in a response also applies HTML sandbox restrictions; it is ignored in a Report-Only header and in meta. Selecting the loosest of multiple enforced policies is incorrect: every applicable policy contributes its restriction. A script source policy, the sandbox script flag and SOP answer different questions. For an embedded preview, granting only capabilities it needs and reading the remaining flags explicitly is more useful than merely recording that a sandbox exists.
Which environment does secure context describe?
Secure context is an environment condition used when exposing powerful browser features. HTTPS is the basic ordinary top-level document example; HTTP loopback addresses in 127.0.0.0/8 and ::1 are also considered potentially trustworthy. localhost names have a trustworthy local-resolution qualification; file and vendor-scheme behavior should not be reduced to one universal URL rule. Current HTML uses the environment’s top-level creation URL context, and a worker’s owner. An HTTPS iframe inside a public HTTP parent cannot be classified solely from its own address.
isSecureContext reports the real environment result; neither origin serialization nor a URL-prefix comparison replaces it. An opaque sandbox origin can coexist with a secure context, so those labels should remain independent. A secure environment also does not guarantee user permission, Permissions Policy approval or API availability. Ordinary fetch exists in HTTP contexts too. The context-denied animation explains a separate secure-context gate; it does not depict ordinary read-only fetch as requiring HTTPS.
2. Red · Trust & Impact
Read every scenario without motion
Report vs enforce
- Same read-only operation
The normal row uses enforce disposition and connectSources self. The request origin matches the Atlas document; requestSent is true and violation false. This result belongs only to connection-source policy.
- Policy table
- self / enforce / sent true
- Boundary review
- Not yet evaluated
- Operation result
- Not yet evaluated
- Enforced block
The none list does not match in connect-denied. Enforcement yields requestSent false and violation true; no arrival of the read-only GET at the server is assumed.
- Policy table
- self / enforce / sent true
- Boundary review
- none / enforce / sent false
- Operation result
- Not yet evaluated
- Report continuation
Report-only with none also yields violation true, but requestSent remains true. Treating a diagnostic as successful blocking erases the disposition difference.
- Policy table
- self / enforce / sent true
- Boundary review
- none / enforce / sent false
- Operation result
- none / report / sent true
- Report delivery is separate
A local diagnostic is not a report delivered to a reporting endpoint. The table runs no HTTP or browser reporting; external report receipt requires separate recipient evidence.
- Policy table
- Local diagnostic ≠ delivered report
- Boundary review
- none / enforce / sent false
- Operation result
- none / report / sent true
- Do not add authority
CSP allowing a connection does not grant server access. CORS, cookies and object policy are separate gates; a read-only response does not prove all of them correct.
- Policy table
- Local diagnostic ≠ delivered report
- Boundary review
- Connection policy ≠ server grant
- Operation result
- none / report / sent true
- Name the correct effects
The result records local blocking for enforce and violation with continuation for report. This narrow self/none example does not imply a full CSP parser, nonce/hash or redirect behavior.
- Policy table
- Local diagnostic ≠ delivered report
- Boundary review
- Connection policy ≠ server grant
- Operation result
- Disposition-specific outcomes retained
Context flags
- HTTPS appearance
Atlas may be an HTTPS Document, but http-ancestor has a public HTTP top-level context and expectedSecure false. Reading only the child URL cannot determine the whole context decision.
- Policy table
- HTTPS child / HTTP ancestor / false
- Boundary review
- Not yet evaluated
- Operation result
- Not yet evaluated
- Sandbox distinction
The allow-scripts row has scriptsAllowed true, formsAllowed false and originKind opaque. Script permission grants neither forms nor a tuple origin; flag effects are not conflated.
- Policy table
- HTTPS child / HTTP ancestor / false
- Boundary review
- Scripts true / forms false / opaque
- Operation result
- Not yet evaluated
- Secure opaque example
The HTTPS opaque-sandbox context has expectedSecure true. Being secure is neither same-origin identity nor a permission grant; opaque identity remains a separate trust assumption.
- Policy table
- HTTPS child / HTTP ancestor / false
- Boundary review
- Scripts true / forms false / opaque
- Operation result
- Opaque / secure true / no permission grant
- Read framing direction
frame-src checks child URLs from the parent; frame-ancestors checks every ancestor from the child. They have different response owners and operation directions.
- Policy table
- Parent frame-src / child frame-ancestors
- Boundary review
- Scripts true / forms false / opaque
- Operation result
- Opaque / secure true / no permission grant
- Check delivery location
frame-ancestors is ignored in meta and has no default-src fallback. Sandbox also does not apply through report-only or meta here; policy text is not proof of enforced flags.
- Policy table
- Parent frame-src / child frame-ancestors
- Boundary review
- Policy delivery/disposition required
- Operation result
- Opaque / secure true / no permission grant
- Three separate decisions
Framing, sandbox and secure context retain separate outcomes. None is reported as a server user/object grant or successful permission UI interaction.
- Policy table
- Parent frame-src / child frame-ancestors
- Boundary review
- Policy delivery/disposition required
- Operation result
- Framing / flags / secure context separate
ASSUMPTION · BOUNDARY · CONTROL
A violation and a stopped request
The normal and connect-denied branches use the same read-only endpoint; the enforced connect-src list is what changes. In the denied branch the browser stops at its local check and no GET arrival is shown at the server. The report-only branch records a violation of the same list while the request continues. Its diagnostic is inert local state, not evidence of delivery to a real reporting endpoint. A report record alone does not prove that a request stopped; disposition and the applied policy must be read together.
Receipt of an API response does not mean CSP has completed every security obligation. Ordinary code allowed by the enforced policy still depends on the server’s object policy. This lesson selects a same-origin GET without redirects; CORS, cookie transmission and response exposure are other gates. URL-host equality is not the full algorithm for every CSP source expression; scheme upgrades, redirects, nonce/hash and script-specific rules require wider context.
Name the effect at the right boundary
Treating the preview’s HTTPS URL as a reason to ignore all ancestor context or sandbox restrictions misdescribes its capabilities. A scripts-allowed row is not a forms-allowed row, and an opaque origin serialized as null is not a trusted preview identity. Relaxing more restrictions than needed may expand browser operations, but the affected data or user action depends on the document and application policy. Here the broken assumption is evaluated through a table, without running a script payload or an external target flow.
3. Blue · Secure development & defense
Read every scenario without motion
Policy controls
- Select directive owner
policyRows records browser connection-gate decisions, while contextRows records expectations for supplied creation contexts. Header/disposition ownership, local violations and endpoint receipt are different observation points. normal and report-only carry a GET to the endpoint; connect-denied and the separate context question do not reach it in this flow. report-gap supplies only a violation, leaving disposition, sending and report delivery unknown. The inventory separates script execution, connection, child URL and ancestor permission. Asking which Document response owns the header identifies the correct policy owner.
- Operation inventory
- Four operations / explicit document owners
- Policy review
- Not yet evaluated
- Regression evidence
- Not yet evaluated
- Record disposition
Normal, connect-denied and report-only sent/violation results are compared together. The same none source list produces different sending outcomes by disposition.
- Operation inventory
- Four operations / explicit document owners
- Policy review
- Normal true/false; deny false/true; report true/true
- Regression evidence
- Not yet evaluated
- Record flag outcomes
An empty sandbox token list disables scripts and forms; allow-scripts enables only scripts and allow-forms only forms. All three rows retain opaque originKind.
- Operation inventory
- Four operations / explicit document owners
- Policy review
- Normal true/false; deny false/true; report true/true
- Regression evidence
- Independent scripts/forms / all opaque
- Context comparison
Top HTTPS and loopback are true, public HTTP and HTTP ancestor false. An HTTPS opaque sandbox can be true; context status is recorded separately from origin kind.
- Operation inventory
- Secure context matrix / identity independent
- Policy review
- Normal true/false; deny false/true; report true/true
- Regression evidence
- Independent scripts/forms / all opaque
- Do not merge layers
Multiple enforced policies intersect; one allowance does not erase another rejection. Server access, browser permission and report delivery require their own evidence beyond this local policy table.
- Operation inventory
- Secure context matrix / identity independent
- Policy review
- Enforce intersection / separate external evidence
- Regression evidence
- Independent scripts/forms / all opaque
- Narrow regression result
The comparison retains source list, disposition, flags and context separately. It does not claim a browser parser or permission UI ran; missing evidence remains specific to each decision.
- Operation inventory
- Secure context matrix / identity independent
- Policy review
- Enforce intersection / separate external evidence
- Regression evidence
- Finite policy known / browser enforcement unmeasured
Report gap
- One violation record
policyRows records browser connection-gate decisions, while contextRows records expectations for supplied creation contexts. Header/disposition ownership, local violations and endpoint receipt are different observation points. normal and report-only carry a GET to the endpoint; connect-denied and the separate context question do not reach it in this flow. report-gap supplies only a violation, leaving disposition, sending and report delivery unknown. The review sees only a violation, without disposition, effective policy or request receipt. This observation cannot select enforced blocking over report-only continuation.
- Operation inventory
- Violation known / disposition missing
- Policy review
- Not yet evaluated
- Regression evidence
- Not yet evaluated
- Bound the normal table
PolicyRows describe narrow expected outcomes. Assuming enforcement and writing requestSent false for the missing event would substitute expectations for an event record.
- Operation inventory
- Violation known / disposition missing
- Policy review
- Expected matrix ≠ event evidence
- Regression evidence
- Not yet evaluated
- Leave sending unknown
Request sending remains UNKNOWN in this record. A local diagnostic is also not reporting-recipient receipt; the two unknowns are retained separately.
- Operation inventory
- Violation known / disposition missing
- Policy review
- Expected matrix ≠ event evidence
- Regression evidence
- Request sending/report delivery UNKNOWN
- Required policy context
The Document response owner, enforce/report disposition and effective policy set are needed. Connection requires endpoint context; framing requires parent/ancestor direction.
- Operation inventory
- Needed: owner/disposition/effective policy
- Policy review
- Expected matrix ≠ event evidence
- Regression evidence
- Request sending/report delivery UNKNOWN
- Choose the right observer
Browser enforcement needs browser observation; server receipt needs server records. A violation label cannot replace permission success or a server object grant.
- Operation inventory
- Needed: owner/disposition/effective policy
- Policy review
- Browser and server observers separate
- Regression evidence
- Request sending/report delivery UNKNOWN
- Report a bounded result
The known violation is retained while sending and report delivery remain unknown. New evidence should be compared by disposition while preserving normal and report-only controls.
- Operation inventory
- Needed: owner/disposition/effective policy
- Policy review
- Browser and server observers separate
- Regression evidence
- Retain violation / collect scoped receipt evidence
IMPLEMENTATION · SECURITY CONTROL · VERIFICATION
Bind policy to an operation inventory
policyRows records browser connection-gate decisions, while contextRows records expectations for supplied creation contexts. Header/disposition ownership, local violations and endpoint receipt are different observation points. normal and report-only carry a GET to the endpoint; connect-denied and the separate context question do not reach it in this flow. report-gap supplies only a violation, leaving disposition, sending and report delivery unknown. Maintain separate inventories of code sources, connection destinations, child URLs and embedding ancestors for Atlas. Record the response owning the header, its enforce/report disposition and the sandbox flag set. The ordinary preview and read-only request serve as positive controls; comparisons focus on the selected policy’s expected denial. CSP does not replace input handling, output encoding or server authorization. The CSP3 source used here is a Working Draft; the example teaches the established directive meanings within its declared scope.
Before turning report-only observations into an enforced decision, examine the real application’s normal requirements; do not automatically allow every destination appearing in a violation. Framing permission is checked separately at parent and child; verify that frame-ancestors is ignored in meta and has no default-src fallback. Choose sandbox tokens from task requirements and explain each relaxed flag. Tests compare scripts, forms and origin outcomes, rather than merely the presence of a marker.
The boundary between browser and model evidence
The context table separates HTTPS, a public HTTP ancestor, loopback and an opaque sandbox inside HTTPS. In a real product API feature detection is evaluated alongside isSecureContext; permission or lifecycle errors can have other causes. This fixture computes only the supplied context snapshots and source-list decisions, without running a browser CSP parser, sandbox navigation or permission UI. Server receipt requires server evidence and enforcement requires browser evidence; animated motion does not produce those independent observations.
NOW APPLY IT TO THE CASE
Does a violation record prove the request stopped?
Atlas compares self and none connection policies for the same read-only path. Enforced none stops the request; report-only none produces a violation while allowing it to continue. Preview framing, sandbox flags and secure-context decisions are separate.
Which relationship does the case’s browser policy control? Explain exposure, destination or framing decisions separately from server object permission.
Open the related case file ↗READ THE EXAMPLE TOGETHER
Atlas browser policy decision table
Select a field and examine what it supports and where the evidence ends.
Read the raw artifact and field explanations
{
"profile": {
"documentOrigin": "https://atlas.example.org",
"readOnlyPath": "/notes/title",
"noRedirects": true,
"noActualBrowser": true,
"noActualHTTP": true,
"sourceMatching": "Declared self/none and one explicit HTTPS host; no full CSP parser",
"contextProfile": "Existing ordinary Window snapshots; selected trustworthy URL inputs only"
},
"directions": [
{
"directive": "script-src",
"owner": "Atlas document",
"operation": "script execution source",
"direction": "document -> script source"
},
{
"directive": "connect-src",
"owner": "Atlas document",
"operation": "script connection destination",
"direction": "document -> endpoint"
},
{
"directive": "frame-src",
"owner": "Atlas parent",
"operation": "child document URL",
"direction": "parent -> child"
},
{
"directive": "frame-ancestors",
"owner": "Preview response",
"operation": "allowed embedding ancestors",
"direction": "child <- every ancestor"
}
],
"policyRows": [
{
"case": "normal",
"disposition": "enforce",
"connectSources": [
"self"
],
"requestOrigin": "https://atlas.example.org",
"matched": true,
"requestSent": true,
"violation": false
},
{
"case": "connect-denied",
"disposition": "enforce",
"connectSources": [
"none"
],
"requestOrigin": "https://atlas.example.org",
"matched": false,
"requestSent": false,
"violation": true
},
{
"case": "report-only",
"disposition": "report",
"connectSources": [
"none"
],
"requestOrigin": "https://atlas.example.org",
"matched": false,
"requestSent": true,
"violation": true
}
],
"framing": {
"parentFrameSources": [
"https://preview.example.org"
],
"childFrameAncestors": [
"https://atlas.example.org"
],
"ancestorChain": [
"https://atlas.example.org"
],
"allowedChild": "https://preview.example.org",
"otherChild": "https://catalog.example.org",
"defaultSrcAppliesToFrameAncestors": false,
"frameAncestorsInMetaIgnored": true
},
"sandboxRows": [
{
"tokens": [],
"scriptsAllowed": false,
"formsAllowed": false,
"originKind": "opaque"
},
{
"tokens": [
"allow-scripts"
],
"scriptsAllowed": true,
"formsAllowed": false,
"originKind": "opaque"
},
{
"tokens": [
"allow-forms"
],
"scriptsAllowed": false,
"formsAllowed": true,
"originKind": "opaque"
}
],
"contextRows": [
{
"case": "top-https",
"creationURL": "https://atlas.example.org",
"topLevelCreationURL": "https://atlas.example.org",
"originKind": "tuple",
"expectedSecure": true
},
{
"case": "http-ancestor",
"creationURL": "https://atlas.example.org",
"topLevelCreationURL": "http://catalog.example.org",
"originKind": "tuple",
"expectedSecure": false
},
{
"case": "loopback",
"creationURL": "http://127.0.0.1:4173",
"topLevelCreationURL": "http://127.0.0.1:4173",
"originKind": "tuple",
"expectedSecure": true
},
{
"case": "ordinary-http",
"creationURL": "http://atlas.example.org",
"topLevelCreationURL": "http://atlas.example.org",
"originKind": "tuple",
"expectedSecure": false
},
{
"case": "opaque-sandbox",
"creationURL": "https://preview.example.org",
"topLevelCreationURL": "https://atlas.example.org",
"originKind": "opaque",
"expectedSecure": true
}
],
"delivery": {
"sandboxInReportOnlyIgnored": true,
"sandboxInMetaIgnored": true,
"multipleEnforcePoliciesIntersect": true
},
"boundaries": {
"cspGrantsServerAccess": false,
"sandboxGrantsServerAccess": false,
"secureContextGrantsPermission": false,
"localDiagnosticIsDeliveredReport": false,
"ordinaryFetchRequiresSecureContext": false
}
}- directions
- Maps each directive to its owning document and operation direction.
- policyRows
- Self/none and enforce/report decisions for a same-origin GET.
- sandboxRows
- Script, form and opaque-origin flags have independent results.
- contextRows
- Creation context and origin kind are independent.
Synthetic ordinary Window snapshots and narrow self/none decisions. No full CSP parser, permissions, document navigation, browser or HTTP run.
Two reality checks
frame-src determines who may embed me.
frame-src constrains child destinations; frame-ancestors on the resource response constrains embedding ancestors.
An HTTPS address enables every browser capability.
Environment/ancestor context, sandbox, feature availability and permissions are separate gates; trustworthy exceptions such as loopback also exist.
YOUR TURN
Work through this story.
Predict the outcome, find the evidence boundary, and explain it in your own words.
A report-only connect-src none policy reports a violation. Is the read-only request sent?
- No; every CSP violation automatically blocks networking.
- Yes; selected report-only requestSent=true.
Read the explained answer
Yes; selected report-only requestSent=true. — Report-only produces a violation observation but does not block the operation under this policy.
Why are frame-src and frame-ancestors not the same permission list?
Selected lesson artifact fields; teaching example
- directions[2]
- {"directive":"frame-src","owner":"Atlas parent","operation":"child document URL","direction":"parent -> child"}
- directions[3]
- {"directive":"frame-ancestors","owner":"Preview response","operation":"allowed embedding ancestors","direction":"child <- every ancestor"}
- The parent’s child-URL permission differs from the child’s embedding-ancestor permission.
- Parent frame-src overrides the child-response ancestor policy.
Read the explained answer
The parent’s child-URL permission differs from the child’s embedding-ancestor permission. — frame-src governs parent→child, while frame-ancestors governs child←every ancestor; both policies may need evaluation.
An HTTPS iframe under an HTTP ancestor has secureContext=false, while loopback HTTP may be true. Why is this not just an https-string check, and why is it not server permission?
Read the explained answer
Secure-context evaluation uses selected creation/ancestor context and trustworthiness rules; scheme alone does not determine every outcome. Loopback is a selected trustworthy exception. Secure contexts relate to some browser-feature gates and do not provide application user/action authorization. CSP and sandbox are also not server grants.
□ I included ancestor context rather than scheme alone.
□ I did not count a browser-feature gate as a server grant.
Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples
Sources and scope
- W3C Content Security Policy Level 3 — Working Draft 16 September 2026§3.1–3.3 policy delivery · §6.1.2 connect-src · §6.1.5 frame-src · §6.1.10 script-src · §6.3.2 sandbox · §6.4.2 frame-ancestors · §8.1 multiple policies
- WHATWG HTML — sandboxing§7.1.5 Sandboxing: origin/forms/scripts flags; parse a sandboxing directive
- W3C Secure Contexts§1.1–1.3 documents and owners · §2.2.2–2.2.3 feature detection and HTML integration · §3.1–3.2 potentially trustworthy origin/URL; localhost resolution qualification
- WHATWG HTML — environments and secure contexts§8.1.3.1 environment top-level creation URL · §8.1.3.5 secure context algorithm; worker owner; worklet · isSecureContext getter
- MDN Secure contextsWhen is a context considered secure? top-level/framed documents and workers · Potentially trustworthy URLs/origins; Feature detection