Secure Your Application: 5 Things Every Developer Must Do
A comprehensive guide to implementing essential security measures in your applications, from authentication to data protection.
- Implement Secure Authentication Password Security
// Password hashing with bcrypt
const bcrypt = require('bcrypt');
async function hashPassword(password) {
const saltRounds = 12;
return await bcrypt.hash(password, saltRounds);
}
async function verifyPassword(password, hash) {
return await bcrypt.compare(password, hash);
}
JWT Implementation
// JWT token generation and verification
const jwt = require('jsonwebtoken');
function generateToken(user) {
return jwt.sign(
{ id: user.id, role: user.role },
process.env.JWT_SECRET,
{ expiresIn: '1h' }
);
}
function verifyToken(token) {
try {
return jwt.verify(token, process.env.JWT_SECRET);
} catch (error) {
throw new Error('Invalid token');
}
}
// MFA implementation
const speakeasy = require('speakeasy');
function generateMFASecret() {
return speakeasy.generateSecret({
name: 'YourApp:user@example.com'
});
}
function verifyMFAToken(secret, token) {
return speakeasy.totp.verify({
secret: secret,
encoding: 'base32',
token: token
});
}
- Protect Against Common Vulnerabilities SQL Injection Prevention
// Using parameterized queries
const { Pool } = require('pg');
const pool = new Pool();
async function getUser(email) {
const query = 'SELECT * FROM users WHERE email = $1';
const values = [email];
return await pool.query(query, values);
}
XSS Protection
// Input sanitization
const xss = require('xss');
function sanitizeInput(input) {
return xss(input, {
whiteList: {}, // No HTML allowed
stripIgnoreTag: true
});
}
// Content Security Policy
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
connectSrc: ["'self'"]
}
}));
CSRF Protection
// CSRF token implementation
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });
app.use(csrfProtection);
app.get('/form', csrfProtection, (req, res) => {
res.render('form', { csrfToken: req.csrfToken() });
});
- Secure Data Transmission HTTPS Implementation
// Express HTTPS setup
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('private.key'),
cert: fs.readFileSync('certificate.crt')
};
https.createServer(options, app).listen(443, () => {
console.log('HTTPS server running on port 443');
});
API Security
// Rate limiting
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
});
app.use('/api/', limiter);
// API key validation
function validateApiKey(req, res, next) {
const apiKey = req.headers['x-api-key'];
if (!apiKey || !isValidApiKey(apiKey)) {
return res.status(401).json({ error: 'Invalid API key' });
}
next();
}
- Secure Data Storage Encryption at Rest
// Data encryption
const crypto = require('crypto');
function encryptData(data, key) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
let encrypted = cipher.update(JSON.stringify(data), 'utf8', 'hex');
encrypted += cipher.final('hex');
const authTag = cipher.getAuthTag();
return {
iv: iv.toString('hex'),
encrypted,
authTag: authTag.toString('hex')
};
}
function decryptData(encryptedData, key) {
const decipher = crypto.createDecipheriv(
'aes-256-gcm',
key,
Buffer.from(encryptedData.iv, 'hex')
);
decipher.setAuthTag(Buffer.from(encryptedData.authTag, 'hex'));
let decrypted = decipher.update(encryptedData.encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return JSON.parse(decrypted);
}
Secure File Storage
// Secure file upload
const multer = require('multer');
const path = require('path');
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname));
}
});
const upload = multer({
storage: storage,
fileFilter: (req, file, cb) => {
const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];
if (!allowedTypes.includes(file.mimetype)) {
cb(new Error('Invalid file type'), false);
return;
}
cb(null, true);
},
limits: {
fileSize: 5 * 1024 * 1024 // 5MB
}
});
- Implement Security Monitoring Logging
// Security logging
const winston = require('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' })
]
});
function logSecurityEvent(event) {
logger.info('Security Event', {
timestamp: new Date().toISOString(),
event: event.type,
user: event.user,
ip: event.ip,
details: event.details
});
}
Error Handling
// Secure error handling
app.use((err, req, res, next) => {
logger.error('Application Error', {
error: err.message,
stack: err.stack,
path: req.path,
method: req.method,
ip: req.ip
});
res.status(500).json({
error: 'An internal server error occurred'
});
});
Best Practices
- Environment Variables
// Environment configuration
require('dotenv').config();
const config = {
jwtSecret: process.env.JWT_SECRET,
databaseUrl: process.env.DATABASE_URL,
apiKey: process.env.API_KEY
};
- Security Headers
// Security headers middleware
const helmet = require('helmet');
app.use(helmet());
app.use(helmet.noSniff());
app.use(helmet.frameguard({ action: 'deny' }));
app.use(helmet.xssFilter());
- Regular Security Audits
// Security audit logging
function auditSecurityEvent(event) {
const auditLog = {
timestamp: new Date().toISOString(),
event: event.type,
user: event.user,
action: event.action,
resource: event.resource,
status: event.status
};
// Store in secure audit log
storeAuditLog(auditLog);
}
Conclusion
This guide has covered:
Secure authentication implementation
Protection against common vulnerabilities
Secure data transmission
Secure data storage
Security monitoring and logging
Best practices for application security
Next Steps
Review your current security measures
Implement missing security features
Set up security monitoring
Conduct security testing
Create security documentation
Resources
OWASP Security Cheat Sheet
Node.js Security Best Practices
Express Security Best Practices
JWT Security Best Practices
Citations
OWASP Top 10
NIST Cybersecurity Framework
CWE Top 25
OWASP Application Security Verification Standard
๐ Ready to kickstart your tech career?
๐ [Apply to 10000Coders]
๐ [Learn Web Development for Free]
๐ [See how we helped 2500+ students get jobs]
Top comments (0)