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-violationsSecure 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
- How do you prevent XSS attacks?
- What's the difference between authentication and authorization?
- How do you securely store sensitive data?
- 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