Web Security Guide 2026: Protect Your Applications

πŸ“… May 17, 2026‒⏱️ 18 min readβ€’πŸ·οΈ Security, Web Development

Learn essential web security practices. Protect your applications from XSS, CSRF, SQL injection, and other common vulnerabilities with practical examples and best practices.

πŸ”’ OWASP Top 10 (2026)

  1. Broken Access Control
  2. Cryptographic Failures
  3. Injection (SQL, XSS)
  4. Insecure Design
  5. Security Misconfiguration
  6. Vulnerable Components
  7. Authentication Failures
  8. Data Integrity Failures
  9. Logging & Monitoring Failures
  10. Server-Side Request Forgery (SSRF)

⚠️ Common Vulnerabilities

1. Cross-Site Scripting (XSS)

Injecting malicious scripts into web pages viewed by other users.

// ❌ Vulnerable Code
<div innerHTML={userInput}></div>

// βœ… Safe Code
import DOMPurify from 'dompurify'
<div innerHTML={DOMPurify.sanitize(userInput)}></div>

// React automatically escapes
<div>{userInput}</div>

// Prevention:
β€’ Escape user input
β€’ Use Content Security Policy (CSP)
β€’ Sanitize HTML
β€’ Validate input

2. SQL Injection

// ❌ Vulnerable
const query = `SELECT * FROM users WHERE id = ${userId}`

// βœ… Safe - Parameterized Query
const query = 'SELECT * FROM users WHERE id = ?'
db.query(query, [userId])

// βœ… Safe - ORM
const user = await User.findByPk(userId)

// Prevention:
β€’ Use parameterized queries
β€’ Use ORMs (Sequelize, Prisma)
β€’ Validate input
β€’ Least privilege database access

3. Cross-Site Request Forgery (CSRF)

// βœ… CSRF Token
// Backend
app.use(csrf())
app.get('/form', (req, res) => {
  res.render('form', { csrfToken: req.csrfToken() })
})

// Frontend
<form method="POST">
  <input type="hidden" name="_csrf" value={csrfToken} />
  <button type="submit">Submit</button>
</form>

// Prevention:
β€’ CSRF tokens
β€’ SameSite cookies
β€’ Verify Origin/Referer headers
β€’ Double submit cookies

πŸ” Authentication & Authorization

Password Security

// βœ… Hash Passwords with bcrypt
const bcrypt = require('bcrypt')

// Register
const hashedPassword = await bcrypt.hash(password, 10)
await User.create({ email, password: hashedPassword })

// Login
const user = await User.findOne({ where: { email } })
const isValid = await bcrypt.compare(password, user.password)

// Best Practices:
β€’ Never store plain text passwords
β€’ Use bcrypt, argon2, or scrypt
β€’ Salt rounds: 10-12
β€’ Enforce strong password policy
β€’ Implement rate limiting
β€’ Use 2FA/MFA

JWT Security

const jwt = require('jsonwebtoken')

// βœ… Generate Token
const token = jwt.sign(
  { userId: user.id, role: user.role },
  process.env.JWT_SECRET,
  { expiresIn: '1h' }
)

// βœ… Verify Token
const decoded = jwt.verify(token, process.env.JWT_SECRET)

// Best Practices:
β€’ Use strong secret (256-bit)
β€’ Short expiration time
β€’ Refresh tokens for long sessions
β€’ Store in httpOnly cookies
β€’ Validate on every request
β€’ Implement token blacklist for logout

🌐 HTTPS & TLS

Why HTTPS?

  • Encryption: Data encrypted in transit
  • Authentication: Verify server identity
  • Integrity: Detect tampering
  • SEO: Google ranking factor
  • Trust: Browser security indicators
// Free SSL Certificates
β€’ Let's Encrypt (certbot)
β€’ Cloudflare
β€’ AWS Certificate Manager
β€’ Vercel/Netlify (automatic)

// Security Headers
app.use((req, res, next) => {
  res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')
  res.setHeader('X-Content-Type-Options', 'nosniff')
  res.setHeader('X-Frame-Options', 'DENY')
  res.setHeader('X-XSS-Protection', '1; mode=block')
  next()
})

πŸ›‘οΈ Content Security Policy (CSP)

// CSP Header
Content-Security-Policy: 
  default-src 'self';
  script-src 'self' 'unsafe-inline' https://cdn.example.com;
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: https:;
  font-src 'self' https://fonts.gstatic.com;
  connect-src 'self' https://api.example.com;
  frame-ancestors 'none';

// Next.js Example
// next.config.js
const securityHeaders = [
  {
    key: 'Content-Security-Policy',
    value: "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline';"
  }
]

module.exports = {
  async headers() {
    return [{ source: '/:path*', headers: securityHeaders }]
  }
}

πŸ” Input Validation

// βœ… Validate with Zod
import { z } from 'zod'

const userSchema = z.object({
  email: z.string().email(),
  password: z.string().min(8).max(100),
  age: z.number().min(18).max(120)
})

try {
  const validData = userSchema.parse(req.body)
} catch (error) {
  return res.status(400).json({ error: error.errors })
}

// βœ… Sanitize Input
import validator from 'validator'

const email = validator.normalizeEmail(req.body.email)
const name = validator.escape(req.body.name)

// Rules:
β€’ Validate on client AND server
β€’ Whitelist, don't blacklist
β€’ Sanitize before storage
β€’ Validate data types
β€’ Check length limits

🚨 Rate Limiting

// Express Rate Limit
const rateLimit = require('express-rate-limit')

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // Limit each IP to 100 requests per windowMs
  message: 'Too many requests, please try again later.'
})

app.use('/api/', limiter)

// Login Rate Limit (stricter)
const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5,
  skipSuccessfulRequests: true
})

app.post('/api/login', loginLimiter, loginHandler)

// Benefits:
β€’ Prevent brute force attacks
β€’ Prevent DDoS
β€’ Reduce server load
β€’ Fair resource usage

πŸ“‹ Security Checklist

  • ☐ HTTPS enabled everywhere
  • ☐ Security headers configured
  • ☐ Input validation (client & server)
  • ☐ Output encoding/escaping
  • ☐ Parameterized queries (no SQL injection)
  • ☐ CSRF protection
  • ☐ XSS protection (CSP)
  • ☐ Password hashing (bcrypt)
  • ☐ JWT with short expiration
  • ☐ Rate limiting
  • ☐ Dependencies updated
  • ☐ Error handling (no sensitive info)
  • ☐ Logging & monitoring
  • ☐ Regular security audits

🎯 Conclusion

Web security is not optionalβ€”it's essential. Implement defense in depth: multiple layers of security. Stay updated with OWASP guidelines, use security tools, and make security part of your development process from day one.

πŸ” Generate Secure Passwords

Need strong passwords? Use our Password Generator to create secure, random passwords.

Generate Password β†’