Hacker DirectoryHacker Directory

WEB / WEB-11.04

CSP, sandbox and secure context

Separate browser policy boundaries for connections, execution, embedding and environments.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

Allowed GET

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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

  1. 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
  2. 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
  3. 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
  4. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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

  1. 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
  2. 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
  3. 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
  4. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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?

  1. No; every CSP violation automatically blocks networking.
  2. 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"}
  1. The parent’s child-URL permission differs from the child’s embedding-ancestor permission.
  2. 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