Web Security Basics in JavaScript

Introduction

JavaScript apps face common web risks: XSS, CSRF, leaked secrets, and vulnerable dependencies. You do not need to be a security engineer to ship safely—this chapter lists practical habits for front-end and Node developers learning full-stack basics.

Prerequisites

XSS — Cross-Site Scripting

Attackers inject script via user content. Defense:

javascript
// Prefer textContent for user data
const userName = "<img onerror=alert(1)>";
const el = document.createElement("p");
el.textContent = userName;
document.body.appendChild(el);

Avoid innerHTML with untrusted strings. Frameworks escape by default—do not disable escaping.

CSRF — Cross-Site Request Forgery

Browsers send cookies automatically. State-changing APIs should use:

  • CSRF tokens for cookie-based sessions
  • SameSite cookie attributes
  • Or token auth (Authorization header) instead of cookies for APIs

Never Trust Client Input

Validate on the server even if the UI validates:

javascript
// server-side check (concept)
function createUser(body) {
  if (!body.email?.includes("@")) {
    throw new Error("invalid email");
  }
  if (body.role !== "member" && body.role !== "admin") {
    throw new Error("invalid role");
  }
}

Secrets and API Keys

  • Store secrets in environment variables or secret managers
  • Never commit .env with real keys
  • Never embed private keys in browser JavaScript bundles

HTTPS

Serve production sites over HTTPS so traffic is encrypted. Terminate TLS at your host or reverse proxy.

Security Headers (Server)

Set headers such as:

  • Content-Security-Policy — restrict script sources
  • X-Content-Type-Options: nosniff
  • Strict-Transport-Security — force HTTPS

Frameworks and middleware add these—learn what your stack enables.

Dependency Security

bash
npm audit
npm audit fix

Review critical findings; pinning versions in package-lock.json helps reproducibility (npm chapter).

Authentication Basics (High Level)

  • Hash passwords with established libraries (bcrypt, argon2)—never plain text
  • Use httpOnly, secure cookies for session tokens when applicable
  • Prefer established auth providers or libraries instead of custom crypto

Mini Example: Sanitize Display Name (Simple)

javascript
function escapeHtml(text) {
  return String(text)
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll('"', "&quot;");
}
 
const input = '"><script>alert(1)</script>';
const safe = escapeHtml(input);
console.log(safe);

Use a maintained library for HTML sanitization if you must render rich HTML.

FAQ

Is eval safe?

Avoid eval and new Function(userInput)—they execute arbitrary code.

CORS a security bug?

CORS is a browser restriction, not a substitute for server auth—always authorize on the server.

What comes next?

Deployment and running Node (optional ops chapter) or advanced topics from the curriculum plan.