Security Best Practices

Security is crucial in modern web applications. Understanding common vulnerabilities and their prevention helps build safer applications.

Cross-Site Scripting (XSS)

// Bad - vulnerable to XSS
element.innerHTML = userInput;

// Good - escape HTML
element.textContent = userInput;

// Using DOMPurify for HTML content
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);

// React's automatic escaping
function Component({ userInput }) {
  return <div>{userInput}</div>; // Automatically escaped
}

Cross-Site Request Forgery (CSRF)

// Include CSRF token in requests
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;

fetch('/api/data', {
  method: 'POST',
  headers: {
    'CSRF-Token': csrfToken
  },
  credentials: 'include'
});

// Using Axios with CSRF protection
axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken;
axios.defaults.withCredentials = true;

Content Security Policy (CSP)

// CSP Header
Content-Security-Policy: default-src 'self';
  script-src 'self' 'nonce-random123';
  style-src 'self' 'unsafe-inline';
  img-src 'self' https:;

// Nonce-based script loading
<script nonce="random123">
  // Trusted script
</script>

// Report-only mode
Content-Security-Policy-Report-Only: 
  default-src 'self';
  report-uri /csp-violations

Secure Authentication

// Password hashing
import bcrypt from 'bcrypt';

async function hashPassword(password) {
  const salt = await bcrypt.genSalt(10);
  return bcrypt.hash(password, salt);
}

// JWT handling
import jwt from 'jsonwebtoken';

function createToken(user) {
  return jwt.sign(
    { id: user.id },
    process.env.JWT_SECRET,
    { expiresIn: '1h' }
  );
}

// HTTP-only cookies
res.cookie('token', token, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict'
});

Input Validation

// Server-side validation
function validateUser(data) {
  const schema = Joi.object({
    username: Joi.string().alphanum().min(3).max(30),
    email: Joi.string().email(),
    password: Joi.string().pattern(/^[a-zA-Z0-9]{8,30}$/)
  });
  
  return schema.validate(data);
}

// Sanitize SQL queries
const query = 'SELECT * FROM users WHERE id = ?';
db.query(query, [userId]); // Use parameterized queries

// Validate file uploads
function validateFile(file) {
  const allowedTypes = ['image/jpeg', 'image/png'];
  const maxSize = 5 * 1024 * 1024; // 5MB
  
  return (
    allowedTypes.includes(file.mimetype) &&
    file.size <= maxSize
  );
}

Common Interview Follow-up Questions

  1. How do you prevent XSS attacks?
  2. What's the difference between authentication and authorization?
  3. How do you securely store sensitive data?
  4. What are the best practices for handling user sessions?

Best Practices

  • Always validate input on both client and server
  • Use HTTPS everywhere
  • Implement proper authentication and authorization
  • Keep dependencies updated
  • Follow the principle of least privilege
  • Implement proper error handling