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:
// 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
SameSitecookie attributes- Or token auth (
Authorizationheader) instead of cookies for APIs
Never Trust Client Input
Validate on the server even if the UI validates:
// 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
.envwith 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 sourcesX-Content-Type-Options: nosniffStrict-Transport-Security— force HTTPS
Frameworks and middleware add these—learn what your stack enables.
Dependency Security
npm audit
npm audit fixReview 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)
function escapeHtml(text) {
return String(text)
.replaceAll("&", "&")
.replaceAll("<", "<")
.replaceAll(">", ">")
.replaceAll('"', """);
}
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.