Secure Coding: Injection, XSS, CSRF & Path Traversal
Secure coding treats security as integrated throughout development -- input validation, proper auth checks, avoiding known vulnerability patterns -- rather than a separate audit layered on afterward.
SQL Injection
// VULNERABLE: user input concatenated directly into the query --
// an attacker's input can alter the query's actual logic
const query = `SELECT * FROM users WHERE name = '${userInput}'`;
// userInput = "' OR '1'='1" bypasses the WHERE clause entirely
// SAFE: parameterized query -- input is bound strictly as DATA,
// never interpreted as SQL syntax, regardless of its content
db.query('SELECT * FROM users WHERE name = ?', [userInput]);Cross-Site Scripting (XSS)
// VULNERABLE: rendering user content as raw HTML
element.innerHTML = userComment;
// userComment = '<script>stealCookies()</script>' executes for every viewer
// SAFE: render as text, not HTML -- the browser escapes it automatically
element.textContent = userComment;
// Additional layer: Content-Security-Policy header restricts what
// scripts can execute at all, even if some XSS slips through
// Content-Security-Policy: script-src 'self'CSRF (Cross-Site Request Forgery)
<!-- A malicious site can trigger a state-changing request to your
site -- the browser auto-attaches cookies to ANY request,
even one initiated from a completely different page.
CSRF token: a unique, unpredictable value the legitimate site
embeds in its own forms and validates server-side. A malicious
third-party page has no way to know or forge this value. -->
<form action="/transfer" method="POST">
<input type="hidden" name="csrf_token" value="a1b2c3...">
<input name="amount">
</form>Path Traversal
// VULNERABLE: user-controlled filename can escape the intended directory
readFile(baseDir + userSuppliedFilename);
// userSuppliedFilename = '../../../etc/passwd'
// SAFE: resolve the final path and verify it's still WITHIN the
// intended base directory before accessing it
const resolved = path.resolve(baseDir, userSuppliedFilename);
if (!resolved.startsWith(path.resolve(baseDir))) {
throw new Error('Invalid path');
}Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free