#META_LECTURE#: #TITLE#

Modified: #LAST_MODIFIED#
Humla v#HUMLA_VERSION#
Browser Networking

Browser Networking

Connection Management

Network Security

Mashups

XHR

XMLHttpRequest (XHR)

  • Interface to utilize HTTP protocol in JavaScript
    • standardized by at W3C
    • basis for AJAX
      • Asynchronous JavaScript and XML
  • Typical usage
    1. Browser loads a page that includes a script
    2. User clicks on a HTML element
      • it triggers a JavaScript function
    3. The function invokes a service through XHR
      • same origin policy, cross-origin resource sharing
    4. The function receives data and modifies HTML in the page

XHR Interface – Key Methods and Properties

  • Method and properties of XHR object
    • open, opens the request, parameters:
          method – method to be used (e.g. GET, PUT, POST),
          url – url of the resource,
          asynch – true to make asynchronous call,
          user, pass – credentials for authentication.
    • onReadyStateChange – JavaScript function object, it is called when readyState changes (uninitialized, loading, loaded, interactive, completed).
    • send, abort – sends or aborts the request (for asynchronous calls)
    • status, statusText – HTTP status code and a corresponding text.
    • responseText, responseXML – response as text or as a DOM document (if possible).
    • onload – event listener to support server push.
  • See , or for a complete reference.

How XHR works

Fetch API

Fetch API

  • XHR is callback-based, Fetch is promise-based
  • Interface to accessing requests and responses
    • Provides global fetch method to fetch resources asynchronously
    • Can be easilly used in service workers
    • Supports CORS and other extensions to HTTP
  • Interfaces
    • Request – represents a request to be made
    • Response – represents a response to a request
    • Headers – represents response/request headers
  • Basic usage:
  • 						async function logMovies() {
    							const response = await fetch("http://example.com/movies.json");
    							const movies = await response.json();
    							console.log(movies);
    						}

Making request

  • A fetch function is available in global window
  • It takes path and returns Promise
  • 						fetch('https://api.github.com/users/tomvit')
    							.then(response => response.json())
    							.then(data => console.log(data))
    							.catch(error => console.error('Error:', error));
  • You can make no-cors request
    • With Fetch, the request will be handled as with putting src to img
    						fetch('https://google.com', {
    							mode: 'no-cors',
    						  }).then(function (response) {
    							console.log(response.type); 
    						  });
  • You can access low-level body stream
    • With XHR, the whole responseText would be loaded into memory.
    • With Fetch, you can read chunks of response and cancel the stream when needed.
Security Mechanisms

Same Origin Policy

Scripting Attacks

Overview of Web Threats

  • Scripting/Web attacks
    • CSRF: attacker causes a user's browser to send an authenticated request
    • XSS: attacker gets script to run in a trusted origin (steal data / act as user)
    • Clickjacking: victim is tricked into clicking UI elements
  • Modern context
    • Single Page Apps (SPAs), APIs, OAuth logins, third-party scripts
    • Browsers added new defenses: SameSite cookies, CSP, CORS, Trusted Types
  • Roles in security scenarios
    • Alice, Bob: regular users / sites
    • Eve: passive attacker, man in the middle (MITM) (observes, phishes)
    • Mallory: active attacker (injects content, modifies requests, drives victim browser)

Modern Web Context

  • Single Page Apps (SPAs)
    • Initial HTML shell + heavy client-side rendering
    • Many background requests via fetch/XHR; History API routing
    • More DOM manipulation ⇒ higher risk of DOM-based XSS
  • APIs (JSON/GraphQL backends)
    • UI often calls api.* subdomain or separate origin
    • CORS and preflight (OPTIONS) become common
    • Auth choices:
      • Cookies ⇒ need CSRF defenses (SameSite, tokens, Origin check)
      • Bearer tokens ⇒ no classic CSRF, but XSS can steal tokens
  • OAuth / OpenID Connect logins
    • Redirect-based flows (IdP → app) with state/nonce validation
    • Token storage and cookie policies affect security and reliability
  • Third-party scripts
    • Analytics, tag managers, widgets run with same privileges as first-party JS
    • Supply-chain risk; mitigate with CSP (script-src), SRI, and limiting connect-src

Recall: State, Sessions, and Cookies

  • HTTP is stateless; sites add state via tokens
    • Cookies (session cookies, persistent cookies)
    • Bearer tokens (often in Authorization: Bearer ...)
  • Session management patterns
    • Stateful: server stores session data
    • Stateless: signed tokens (e.g., JWT) stored client-side; server validates each request
  • Cookie flags
    • Secure: only over HTTPS
    • HttpOnly: not readable by JavaScript
      • Mitigates some XSS cookie theft, but not all attack scenarios
    • SameSite: limits cross-site cookie sending
      • Major CSRF mitigation

Cross-site Request Forgery (CSRF)

  • How it works
    • Victim’s browser sends a request to bank.com with user's credentials (cookies)
    • Attacker cannot read the response (SOP), but the side effect may still happen
  • CSRF today
    • Many browsers now default to SameSite=Lax (reduces CSRF via cross-site navigation)
    • But CSRF is still relevant
      • misconfigured SameSite=None, legacy apps, subdomain issues, OAuth flows
  • Typical attack shapes
    • Cross-site <form method="POST"> submit
    • State-changing GET is still a bug, but many frameworks avoid it now
  • Modern best practice
    • Use CSRF tokens (synchronizer token pattern) or double-submit cookie
    • Set cookies: SameSite=Lax (default) or Strict where possible
      • only use None; Secure when required
    • Validate Origin header for state-changing requests (often better than Referer)
    • Re-auth / step-up auth for high-risk actions

CSRF Example

  • Attacker page causes a victim browser to submit a form to a target origin
<form action="https://bank.com/transfer" method="POST">
  <input type="hidden" name="to" value="mallory" />
  <input type="hidden" name="amount" value="50000" />
</form>
<script>document.forms[0].submit()</script>
  • What makes this work?
    • If the browser includes cookies for bank.com on this cross-site POST
    • If server does not require or validate a CSRF token (or Origin)
  • Why attackers like it
    • No need to read responses; only need the action to succeed

CSRF Tokens

  • Goal
    • Prevent cross-site request forgery even when cookies are attached by the browser
    • Server accepts a state-changing request only if it contains a secret token
  • Synchronizer Token Pattern (most common)
    • Server creates a random token bound to the user session
    • Token is embedded into HTML (form field) or sent as a header by JS
    • On POST/PUT/DELETE: server verifies token matches the session
  • Why it works
    • Attacker can trigger a cross-site request (e.g., <form>)
      • but cannot read the response page to obtain the token (prevented by SOP)
    • Guessing a random token is not possible
  • Implementation notes
    • Regenerate tokens periodically (or per form) and invalidate on logout
    • Protect token delivery with HTTPS; avoid exposing it to third-party origins
    • Use together with SameSite cookies and Origin checks
    						
    ...

Cross-site Scripting (XSS)

  • How XSS works
    • Attacker-controlled script runs in a trusted origin (e.g., https://app.com)
    • Can read/modify DOM, make same-origin requests, extract data, act as the user
  • Types
    • Stored: payload stored on server (posts, profiles)
    • Reflected: payload in request (query param) reflected into HTML
    • DOM-based: client-side JS inserts untrusted data into DOM unsafely
  • Today's prevention
    • Many apps use frameworks that reduce HTML injection
      • But DOM-XSS via unsafe sinks still happens
    • Third-party scripts and supply-chain risks can lead to "XSS-like" outcomes

XSS: What Attackers Do Today

  • Common impact
    • Session hijack is harder if cookies are HttpOnly, but attackers can still:
      • Perform actions as the user (same-origin fetch)
      • Steal sensitive DOM data (CSRF tokens in DOM, PII rendered in page)
      • Keylog / credential phishing overlays
      • Token theft when apps store tokens in localStorage
  • Mitigations
    • Output encoding + safe templating
    • Sanitize HTML if you must render it (allowlist-based sanitizers)
    • Content Security Policy (CSP) (reduce exploitability)
    • Trusted Types (Chrome/Chromium): block DOM-XSS sinks unless explicitly allowed

Content Security Policy (CSP)

  • Goal
    • Mitigate XSS attacks by restricting what the page can load and execute
    • Browser enforces a policy sent by the server (HTTP header or <meta>)
  • Core idea
    • Define allowlists for resource types (scripts, styles, images, connections, frames, ...)
    • Block unexpected code execution (e.g., injected <script>, inline handlers)
  • Common directives
    • script-src: where scripts can come from; can require 'nonce-...' / hashes
    • connect-src: where JS can send requests (fetch/XHR/WebSocket)
    • img-src, style-src, font-src: resource allowlists
    • object-src 'none': disable plugin content
    • base-uri: restrict <base> tag abuse
    • frame-ancestors: who may embed the page (clickjacking defense)

Nonce-based CSP Example

  • Policy (sent as HTTP response header)
    • Only load scripts from self
    • only execute inline scripts that carry the correct nonce
    • Allow XHR/WebSocket only to own origin and a trusted API
    • Prevent plugins and clickjacking
    Content-Security-Policy:
      default-src 'self';
      script-src 'self' 'nonce-ABC123';
      connect-src 'self' https://api.example.com;
      object-src 'none';
      base-uri 'self';
      frame-ancestors 'none'
  • Scripts in a page
    • server must inject the same nonce into allowed inline scripts
    <script nonce="ABC123">
      // allowed inline script
      window.appBoot();
    </script>
    
    <script>
      // blocked inline script (missing nonce)
      alert('XSS');
    </script>

XSS Example: DOM-based

  • Bug pattern: untrusted data flows into a dangerous DOM sink
  • // URL: https://app.com/welcome?name=<img src=x onerror=alert(1)>
    const params = new URLSearchParams(location.search);
    const name = params.get("name");
    
    // Dangerous sink:
    document.querySelector("#welcome").innerHTML = "Hi " + name;
  • Fix
    • Use textContent instead of innerHTML
    • If HTML is required, sanitize with a proven library and strict allowlist

Historical XSS Examples

  • Twitter in Sep 2010
    • Injection of JavaScript code to a page using a tweet
    • You posted following tweet to Twitter
    • 								There is a great event happening at 
      								http://someurl.com/@"onmouseover="alert('test xss')"/
    • Twitter parses the link and wraps it with <a> element
    • 								There is a great event happening at 
      								<a href="http://someurl.com/@"onmouseover="alert('test xss')" 
      									target="_blank">http://someurl.com/@"onmouseover=
      									"alert('test xss')"/</a>
    • See details at
  • Other example: Google Contacts

Clickjacking

  • How clickjacking works
    • Attacker tricks a victim into clicking a UI element on a trusted site
    • Technique: embed the trusted site in an <iframe> and overlay it under a decoy button
    • SOP blocks reading iframe contents, but clickjacking only needs the click
  • Example attack concept
  • <div id="decoy">
      Click to claim your prize
      <button>Claim</button>
    </div>
    
    <!-- Invisible/transparent iframe aligned so victim's click hits "Confirm" -->
    <iframe id="targetFrame" src="https://bank.com/transfer/confirm"></iframe>
    
    <style>
    #targetFrame {
      position: absolute;
      top: 120px; left: 90px;   /* align target button under decoy */
      width: 1000px; height: 800px;
      opacity: 0.01; border: 0; /* nearly invisible */
    }
    #decoy { position: relative; z-index: 2; }
    </style>
  • Defenses
    • Content-Security-Policy: frame-ancestors 'none' (or allowlist trusted embedders)

Quick Comparison: CSRF vs XSS

  • CSRF
    • Attacker cannot run code in the target origin
    • Relies on browser automatically attaching credentials (cookies)
    • Defenses: SameSite, CSRF tokens, Origin checks
  • XSS
    • Attacker can run code in the target origin
    • Bypasses CSRF defenses (because requests are same-origin)
    • Defenses: encoding/sanitization, CSP, Trusted Types, reduce secrets in DOM
Cross-origin Resource Sharing Protocol (CORS)

Overview

  • Increasing number of mashup applications
    • client-side mashups involving multiple sites
    • mechanism to control an access to sites from within JavaScript
  • Allow for cross-site HTTP requests
    • HTTP requests for resources from a different domain than the domain of the resource making the request.
  • W3C Recommendation
    • see
    • Browsers support it
      • see at Mozilla

CORS Protocol – GET

  • Read-only resource access via HTTP GET
  • Headers:
    • Origin – identifies the origin of the request
    • Access-Control-Allow-Origin – defines who can access the resource
    • either the full domain name or the wildcard (*) is allowed.

CORS Protocol – other methods and "preflight"

  • Preflight request queries the resource using OPTIONS method
    • requests other than GET (except POST w/o payload) or with custom headers
    • A browser should run preflight automatically for any XHR request meeting preflight conditions
    • The browser caches responses according to Access-Control-Max-Age
JSON and JSONP

Recall: JSON

JSON in JavaScript

JSONP

JSONP in JavaScript