Web Security Best Practices for Modern Applications
SecurityWeb DevelopmentAuthenticationOWASP
Web Security Best Practices for Modern Applications
Security is paramount in modern web applications. Let's explore essential practices to protect your applications.
Authentication
Secure Password Hashing
import * as bcrypt from 'bcrypt';
async function hashPassword(password: string): Promise<string> {
const saltRounds = 12;
return await bcrypt.hash(password, saltRounds);
}
async function verifyPassword(password: string, hash: string): Promise<boolean> {
return await bcrypt.compare(password, hash);
}
JWT Implementation
import * as jwt from 'jsonwebtoken';
const JWT_SECRET = process.env.JWT_SECRET!;
interface TokenPayload {
userId: string;
role: string;
}
function generateToken(payload: TokenPayload): string {
return jwt.sign(payload, JWT_SECRET, {
expiresIn: '1h',
algorithm: 'HS256'
});
}
function verifyToken(token: string): TokenPayload {
try {
return jwt.verify(token, JWT_SECRET) as TokenPayload;
} catch (error) {
throw new Error('Invalid token');
}
}
XSS Prevention
Content Security Policy
// Express middleware
app.use((req, res, next) => {
res.setHeader(
'Content-Security-Policy',
"default-src 'self'; " +
"script-src 'self' 'unsafe-inline' 'unsafe-eval'; " +
"style-src 'self' 'unsafe-inline';"
);
next();
});
Input Sanitization
import { sanitize } from 'dompurify';
function sanitizeUserInput(input: string): string {
return sanitize(input, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a'],
ALLOWED_ATTR: ['href']
});
}
// Usage in React
function CommentDisplay({ comment }: { comment: string }) {
return <div dangerouslySetInnerHTML={{
__html: sanitizeUserInput(comment)
}} />;
}
CSRF Protection
import csurf from 'csurf';
// Express middleware
app.use(csurf());
// React component
function Form() {
const csrfToken = document.querySelector('meta[name="csrf-token"]')
?.getAttribute('content');
return (
<form method="POST" action="/api/submit">
<input type="hidden" name="_csrf" value={csrfToken} />
{/* form fields */}
</form>
);
}
SQL Injection Prevention
import { Pool } from 'pg';
const pool = new Pool();
async function getUserById(id: string) {
// Use parameterized queries
const query = {
text: 'SELECT * FROM users WHERE id = $1',
values: [id],
};
try {
const result = await pool.query(query);
return result.rows[0];
} catch (error) {
console.error('Database error:', error);
throw error;
}
}
Rate Limiting
import rateLimit from '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 from this IP, please try again later'
});
// Apply to all routes
app.use(limiter);
// Apply to specific routes
app.use('/api/login', rateLimit({
windowMs: 60 * 60 * 1000, // 1 hour
max: 5, // 5 attempts per hour
message: 'Too many login attempts, please try again later'
}));
Secure Headers
import helmet from 'helmet';
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
},
},
referrerPolicy: { policy: 'same-origin' }
}));
Best Practices
-
Security Headers
- Use HTTPS
- Set secure cookies
- Implement HSTS
- Enable CORS properly
-
Authentication
- Implement MFA
- Use secure session management
- Implement proper password policies
- Handle logout properly
-
Data Protection
- Encrypt sensitive data
- Implement proper access control
- Regular security audits
- Keep dependencies updated
Security Checklist
interface SecurityChecklist {
authentication: {
passwordHashing: boolean;
mfa: boolean;
sessionManagement: boolean;
};
headers: {
https: boolean;
csp: boolean;
hsts: boolean;
};
dataProtection: {
encryption: boolean;
accessControl: boolean;
backups: boolean;
};
}
const securityAudit: SecurityChecklist = {
authentication: {
passwordHashing: true,
mfa: true,
sessionManagement: true
},
headers: {
https: true,
csp: true,
hsts: true
},
dataProtection: {
encryption: true,
accessControl: true,
backups: true
}
};
Conclusion
Security should be a continuous process, not a one-time implementation. Regular audits and updates are essential to maintain a secure application.