1. Broken Access Control
Vulnerability
Users can access resources or perform actions outside their intended permissions.
Prevention
// Bad - No authorization check
app.get('/admin/users', (req, res) => {
User.find().then(users => res.json(users));
});
// Good - Check permissions
app.get('/admin/users', [
auth,
authorize('admin'),
async (req, res) => {
const users = await User.find();
res.json(users);
}
]);
// Authorization middleware
const authorize = (role) => {
return (req, res, next) => {
if (req.user.role !== role) {
return res.status(403).json({ error: 'Forbidden' });
}
next();
};
};2. Cryptographic Failures
Vulnerability
Sensitive data not properly protected (passwords, credit cards, PII).
Prevention
import bcrypt from 'bcrypt';
import crypto from 'crypto';
// Hash passwords
const hashedPassword = await bcrypt.hash(password, 10);
// Encrypt sensitive data
const algorithm = 'aes-256-gcm';
const key = crypto.scryptSync(password, 'salt', 32);
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(data, 'utf8', 'hex');
encrypted += cipher.final('hex');
const authTag = cipher.getAuthTag();
// Store encrypted with iv and authTag3. Injection
Vulnerability
Untrusted data sent to interpreter as part of command or query.
SQL Injection Prevention
// Bad - Concatenation
const query = `SELECT * FROM users WHERE id = '${userId}'`;
// Good - Parameterized
const query = 'SELECT * FROM users WHERE id = ?';
db.query(query, [userId]);
// Best - ORM
const user = await User.findByPk(userId);NoSQL Injection Prevention
// Bad - Direct injection
const query = { $where: `this.email === '${email}'` };
// Good - Mongoose built-in methods
const user = await User.findOne({ email });4. Insecure Design
Vulnerability
Flaws in design and architecture that enable attacks.
Prevention
- 1Threat modeling: Identify potential threats
- 2Security requirements: Define security needs
- 3Secure defaults: Safe configuration out of the box
- 4Defense in depth: Multiple security layers
5. Security Misconfiguration
Vulnerability
Improper configuration of security settings.
Prevention
// Disable debug mode in production
if (process.env.NODE_ENV === 'production') {
app.disable('x-powered-by');
app.use(helmet());
}
// Secure session configuration
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: true,
httpOnly: true,
maxAge: 3600000,
sameSite: 'strict',
}
}));
// CORS configuration
const corsOptions = {
origin: process.env.ALLOWED_ORIGINS?.split(','),
credentials: true,
};6. Vulnerable and Outdated Components
Vulnerability
Using libraries with known vulnerabilities.
Prevention
# Audit dependencies
npm audit
# Fix vulnerabilities
npm audit fix
# Automated scanning
npm install -g snyk
snyk test7. Identification and Authentication Failures
Vulnerability
Weak authentication, session management, and identity controls.
Prevention
// Strong password requirements
const passwordSchema = Joi.string()
.min(8)
.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[@$!%*?&])/)
.required();
// Rate limiting
import rateLimit from 'express-rate-limit';
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5,
message: 'Too many login attempts',
});
app.post('/login', loginLimiter, loginHandler);
// Multi-factor authentication
const generateOTP = () => {
return speakeasy.totp({
secret: process.env.OTP_SECRET,
encoding: 'base32',
});
};8. Software and Data Integrity Failures
Vulnerability
Code and infrastructure not protected against integrity violations.
Prevention
# Use package-lock.json
npm ci
# Verify dependencies
npm audit verify
# Subresource Integrity (SRI)
<link
rel="stylesheet"
href="style.css"
integrity="sha384-..."
crossorigin="anonymous"
>9. Security Logging and Monitoring Failures
Vulnerability
Insufficient logging and monitoring of security events.
Prevention
import winston from 'winston';
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' }),
],
});
// Log security events
app.use((req, res, next) => {
logger.info({
method: req.method,
url: req.url,
ip: req.ip,
userAgent: req.get('user-agent'),
});
next();
});
// Alert on suspicious activity
if (failedAttempts > 5) {
logger.error('Possible brute force attack', { ip: req.ip });
// Send alert
}10. Server-Side Request Forgery (SSRF)
Vulnerability
Application fetches remote resources without validating user-supplied URLs.
Prevention
import { URL } from 'url';
// Validate URLs
const isValidUrl = (urlString) => {
try {
const url = new URL(urlString);
// Block private IPs
const hostname = url.hostname;
const blocked = ['localhost', '127.0.0.1', '0.0.0.0'];
if (blocked.includes(hostname)) {
return false;
}
// Only allow HTTPS
if (url.protocol !== 'https:') {
return false;
}
// Allowlist domains
const allowedDomains = ['api.example.com'];
if (!allowedDomains.includes(hostname)) {
return false;
}
return true;
} catch {
return false;
}
};
app.post('/fetch', async (req, res) => {
const { url } = req.body;
if (!isValidUrl(url)) {
return res.status(400).json({ error: 'Invalid URL' });
}
const response = await fetch(url);
const data = await response.json();
res.json(data);
});Security Checklist
- [ ] All inputs validated and sanitized
- [ ] Parameterized queries for database access
- [ ] HTTPS enforced
- [ ] Security headers implemented
- [ ] Strong password policies
- [ ] Rate limiting configured
- [ ] Logging and monitoring enabled
- [ ] Dependencies regularly updated
- [ ] Authentication properly implemented
- [ ] Authorization checks on all endpoints
Conclusion
Understanding OWASP Top 10 is crucial for building secure applications. Implement these protections from the start of development.