This article covers foundational web concepts essential for understanding cross-site scripting (XSS) vulnerabilities — focusing on HTTP mechanics, client-side state management, and browser scripting behavior.
HTTP Communication Essentials
Request Methods
- GET: Retrieves resources without side effects. Parameters appear in the URL query string and are visible, limited in length, and cached by default.
- POST: Submits data to be processed (e.g., form submissions, API calls). Payload resides in the request body, supporting larger and more sensitive inputs.
Request Structure
An HTTP request consists of four parts:
- Request line: Method, path, and protocol version.
GET /search?q=test HTTP/1.1 - Headers: Key-value metadata (e.g.,
Accept: application/json,User-Agent: Mozilla/5.0). - Empty line: Separates headers from body (CRLF).
- Body: Present only in POST, PUT, PATCH, etc. May contain JSON, form-encoded data, or binary content.
Example POST request with JSON payload:
POST /v1/comments HTTP/1.1
Host: api.example.org
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
{"post_id": 42, "content": "<script>alert(1)</script>"}
Response Anatomy
A response includes:
- Status line: e.g.,
HTTP/1.1 201 Created - Headers: e.g.,
Content-Type: text/html; charset=utf-8,Set-Cookie: session=abc123; HttpOnly; Secure - Blank line
- Response body: Rendered HTML, JSON, or other payloads
Sample HTML response:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 172
<html><body>
<h2>Welcome, <span id="username">Guest</span></h2>
</body></html>
Core HTTP Characteristics
- Stateless: No built-in memory of prior interactions — sessions require external mechanisms (e.g., cookies, tokens).
- Connection model: Historically connectionless; modern implementations use persistent connections (Keep-Alive) and multiplexing (HTTP/2+).
- Text-based: Human-readable, debug-friendly, but unencrypted unless layered over TLS.
- Status codes: Standardized numeric indicators (e.g., 2xx success, 4xx client error, 5xx server error).
- Extensible: Custom headers (e.g.,
X-Requested-With), methods, and media types enable rich integrations.
Client-Side State: Cookies
Cookies are small, name-value pairs sent by servers and stored by browsers. They accompany subsequent requests to the same origin.
Common Use Cases
- Session tracking: A randomly generated
session_idlinks requests to server-side session storage. - Authentication tokens: Long-lived identifiers (though best practice favors short-lived JWTs or opaque tokens).
- User preferences: Theme, language, layout settings persisted across visits.
- Shopping cart persistence: Temporary item storage before checkout.
Security Attributes
Modern cookies support critical security flags:
Secure: Transmitted only over HTTPS.HttpOnly: Inaccessible to JavaScript (document.cookiereads omit it), mitigating XSS exfiltration.SameSite: Controls cross-origin cookie inclusion (e.g.,SameSite=Laxblocks most CSRF-prone requests).
Server-Side Sessions
Unlike cookies, session data resides entirely on the server — the client holds only a reference (typically via a cookie). This design improves security and scalability.
Key Advantages
- Data confidentiality: Sensitive values (e.g., roles, permissions) never leave the server.
- Storage flexibility: No 4KB size limit per domain like cookies; supports complex objects or database-backed stores.
- Expiration control: Server-enforced timeouts (e.g., 30-minute inactivity) and revocation capabilities.
- Uniform compatibility: Independent of browser-specific cookie policies or third-party blocking.
JavaScript Cookie Interaction
Browsers expose basic cookie manipulation via document.cookie, though its API is intentionally minimal and string-based.
Basic Operations
- Read all accessible cookies:
const all = document.cookie;→ returns semicolon-separated string like"theme=dark; lang=en" - Write or update:
document.cookie = "cart_items=3; path=/; max-age=3600"; - Delete: Set expiry in the past:
document.cookie = "cart_items=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
Note: Cookies are scoped strictly by origin (scheme + host + port). They cannot be read across domains or shared between browsers.
Practical Example: Parsing Cookies Safely
function getCookie(name) {
const cookies = document.cookie.split('; ');
for (const pair of cookies) {
const [key, value] = pair.split('=', 2);
if (key === name) return decodeURIComponent(value);
}
return null;
}
// Usage
const theme = getCookie('theme'); // 'dark'