Web Security - Protecting Your Web Applications from Common Attacks

Web security is a critical concern for every web application. Vulnerabilities can lead to data breaches, user account compromises, and legal consequences.

The OWASP (Open Web Application Security Project) Top 10 lists the most critical web application security risks that every developer should be aware of.

This guide covers the most common web security vulnerabilities and practical strategies to prevent them in your applications.

Cross-Site Scripting (XSS)

XSS attacks inject malicious scripts into web pages viewed by other users. Attackers can steal cookies, session tokens, or redirect users to malicious sites.

JavaScript
XSS prevention by escaping user output
// VULNERABLE - Never inject raw user input into DOM
document.getElementById('output').innerHTML = userInput;

// SAFE - Use textContent instead of innerHTML
document.getElementById('output').textContent = userInput;

// SAFE - Escape HTML characters on the server
function escapeHtml(text) {
  return text
    .replace(/&/g, '&')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;');
}

// Use a Content Security Policy header
// Content-Security-Policy: default-src 'self'; script-src 'self'

Use frameworks like React that auto-escape content by default, and always set a strict Content Security Policy (CSP) header on your server.

Cross-Site Request Forgery (CSRF)

CSRF tricks authenticated users into submitting requests they didn't intend to make. An attacker's website can trigger actions on your site using the victim's session.

JavaScript
CSRF protection with tokens in Express
// Install: npm install csurf
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });

// Add CSRF token to forms
app.get('/form', csrfProtection, (req, res) => {
  res.render('form', { csrfToken: req.csrfToken() });
});

// Validate on POST
app.post('/submit', csrfProtection, (req, res) => {
  res.json({ status: 'ok' });
});

// For APIs: Use SameSite cookie attribute
res.cookie('sessionId', token, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict'
});

SQL Injection Prevention

SQL injection occurs when untrusted data is sent to a database interpreter as part of a command. Always use parameterized queries or prepared statements.

JavaScript
Safe parameterized queries vs vulnerable string concatenation
// VULNERABLE - Never do this
const query = `SELECT * FROM users WHERE email = '${userEmail}'`;

// SAFE - Use parameterized queries
const { rows } = await pool.query(
  'SELECT * FROM users WHERE email = $1',
  [userEmail]
);

// SAFE - Mongoose (MongoDB) auto-sanitizes
const user = await User.findOne({ email: userEmail });

// SAFE - Sequelize with parameterized query
const user = await User.findOne({ where: { email: userEmail } });

Security HTTP Headers

Proper HTTP response headers can prevent many common attacks. Use the helmet package in Express to set secure headers automatically.

JavaScript
Setting security headers with Helmet.js in Express
const helmet = require('helmet');

app.use(helmet()); // Sets multiple security headers at once

// Includes:
// - Content-Security-Policy
// - X-Frame-Options: DENY (prevents clickjacking)
// - X-Content-Type-Options: nosniff
// - Strict-Transport-Security (HSTS)
// - Referrer-Policy
// - Permissions-Policy

Web Security Checklist

  • Always use HTTPS with a valid SSL/TLS certificate
  • Hash passwords with bcrypt, Argon2, or scrypt — never store plain text
  • Implement rate limiting on login and API endpoints
  • Validate and sanitize all user inputs on the server side
  • Use parameterized queries for all database operations
  • Set secure, httpOnly, and SameSite flags on cookies
  • Implement proper CORS configuration to restrict allowed origins
  • Keep dependencies updated and audit with npm audit regularly
  • Never expose stack traces or detailed error messages to users

Conclusion

Web security requires a layered approach — no single technique is enough. By understanding common vulnerabilities like XSS, CSRF, and SQL injection, you can design defenses at every layer of your application.

Make security a core part of development from the start, not an afterthought. Regularly audit dependencies, follow OWASP guidelines, and keep your infrastructure updated.