Explorer
JavaScript

Security Best Practices

JavaScript Theory & Concepts

Security Best Practices in JavaScript

Defending against XSS, CSRF, prototype pollution, injection, and supply chain threats.

📖 The Story & Real-World Analogy

The Medieval Castle Moat and Drawbridge

"A fortified castle does not let unknown travelers walk in through open cellar windows. It has a guarded drawbridge: • **Filtering the water supply**: You boil all river water before pouring it into drinking barrels (Sanitizing user inputs with DOMPurify to prevent XSS). • **Royal Wax Seals**: Every formal request from the king carries a cryptographic wax stamp that cannot be forged by rogue messengers (Anti-CSRF tokens and SameSite cookies). • **Guarding the family recipe vault**: Ensuring no foreign spy can slip toxic ingredients into the royal dough (Preventing Prototype Pollution)!"

Client-side and Node.js JavaScript are primary targets for malicious actors. Applying defense-in-depth ensures applications resist injection, credential theft, and unauthorized actions.

⚙️ How It Works Under The Hood (Step-by-Step)
1

Cross-Site Scripting (XSS) Prevention

Never inject raw user strings via `innerHTML` or `document.write`. Always use `textContent` or sanitize rich text using certified sanitizers like `DOMPurify`.

2

Content Security Policy (CSP)

An HTTP header that restricts where scripts, images, and fonts can load from, preventing unauthorized script execution even if an injection vulnerability exists.

3

Cross-Site Request Forgery (CSRF)

Use `SameSite=Lax` or `SameSite=Strict` on authentication cookies. Combine with anti-CSRF challenge tokens for sensitive state-changing mutations.

4

Prototype Pollution Defense

Deep-merge libraries must reject `__proto__`, `constructor`, and `prototype` keys to prevent attackers from mutating global Object prototypes.

💻 Interactive Code Walkthrough

Safely sanitizing untrusted user inputs and guarding against prototype pollution:

JAVASCRIPT
// 1. Safe Property Assignment (Guarding Prototype Pollution)
function safeSetProperty(target, key, value) {
  // Reject prototype injection vectors
  if (key === "__proto__" || key === "constructor" || key === "prototype") {
    throw new Error("Security Violation: Prototype pollution attempt detected");
  }
  target[key] = value;
}

const safeData = {};
safeSetProperty(safeData, "username", "alice");
console.log("Safe property set:", safeData.username);

try {
  safeSetProperty(safeData, "__proto__", { isAdmin: true });
} catch (err) {
  console.log(err.message);
}

// 2. Safe DOM update (always use textContent for untrusted strings)
// element.textContent = untrustedInput; // Safe: browser treats input as raw text
Console Output:
CODE
Safe property set: alice
Security Violation: Prototype pollution attempt detected
⚠️ Common Pitfalls & Interview Traps
Trap
Using innerHTML with Untrusted User Data

The Risk: `div.innerHTML = userComment;` allows attackers to inject ``, hijacking user sessions.

The Fix: Always use `div.textContent = userComment` or sanitize with `DOMPurify.sanitize(userComment)`.

Trap
Storing Sensitive Tokens in localStorage

The Risk: Any XSS script running on the page can execute `localStorage.getItem("token")` and transmit credentials to an attacker server.

The Fix: Store session tokens in `HttpOnly; Secure; SameSite=Strict` cookies.

⚡ 30-Second Quick Revision Cheat Sheet (TL;DR)
  • ✓ Never trust raw user input: sanitize or use `textContent`.
  • ✓ Never use `eval()` or `new Function()` with dynamic strings.
  • ✓ Protect cookies with `HttpOnly; Secure; SameSite=Strict`.
  • ✓ Deploy a strict Content Security Policy (CSP) header.
  • ✓ Block `__proto__` and `constructor` keys in object-merging utilities.

Finished this lesson?

Mark this chapter complete to update your learning streak and unlock the next lesson.