Browser code under the trusted origin
Cross-site scripting occurs when untrusted data becomes active content in a page and executes with the privileges of the application's origin. The script can read page data, make authenticated requests, alter user-visible actions, capture input, or act through APIs available to the session.
Reflected XSS returns request data in the immediate response. Stored XSS persists the payload and serves it later. DOM-based XSS occurs when client code moves untrusted data into an executable browser sink without a safe server response being necessary.
Context controls
Use templates and UI frameworks that escape data by default. Encode at the final output for the exact context. HTML text, HTML attributes, URLs, JavaScript strings, CSS, and raw markup have different parsing rules. Avoid placing untrusted data in event handlers, script source, style source, tag names, attribute names, or executable URLs.
Use DOM APIs that assign text, not markup. Do not use innerHTML, document writing, dynamic code evaluation, or string-built script. If the product must accept rich HTML, apply a maintained sanitizer with an explicit element, attribute, protocol, and URL policy. Sanitize after the final decode and before insertion.
Defense in depth
A strict Content Security Policy can reduce impact and expose unsafe script patterns. Trusted Types can constrain dangerous DOM sinks in supported applications. HttpOnly reduces direct cookie reads but an injected script can still issue authenticated actions. SameSite cookie behavior does not stop same-origin script.
Minimize sensitive data in the DOM and browser storage. Separate high-risk administrative interfaces by origin when practical. Test stored, reflected, and DOM flows with each output context and client-side route.
Failure and residual risk
Input validation alone cannot preserve legitimate free-form text and stop all XSS. A global interceptor can encode for the wrong context. A sanitizer can be bypassed by parser differences or unsafe later mutation. CSP with broad hosts, inline allowances, or dynamic script trust can provide little protection. Third-party script has the same origin authority as first-party script.
Pomerium boundary
Pomerium can authenticate the browser session before it reaches a protected application. It does not sanitize the application's HTML or client-side DOM operations. XSS in the upstream can act with the authenticated user's application authority. The application must encode output, use safe DOM APIs, constrain script, and keep sensitive actions independently authorized.
Evaluation checklist
- Where can untrusted data enter HTML, attributes, URLs, script, style, or DOM sinks?
- Does the final rendering layer apply the correct encoding for each context?
- Are raw HTML and dangerous DOM APIs absent or protected by an explicit sanitizer policy?
- Does CSP block an unapproved script without relying on a broad source list?
- Can injected script perform a sensitive action without fresh authorization or user-visible confirmation?
- Do tests cover reflected, stored, DOM-based, mutation, and third-party-script paths?
