OWASP Secure Coding Practices
A comprehensive guide to OWASP secure coding guidelines. Learn how to write secure code and prevent common vulnerabilities.
What is OWASP?
The Open Web Application Security Project (OWASP) is a nonprofit foundation that works to improve the security of software. OWASP provides free, open resources including tools, documentation, and community-driven projects.
Key OWASP Resources
Secure Coding Practices
Input Validation
Validate all input data from untrusted sources. Never trust user input.
Guidelines:
- Validate input on the server side (client-side is not enough)
- Use allowlisting over denylisting where possible
- Validate data type, length, format, and range
- Sanitize input before use in queries, commands, or output
- Reject invalid input rather than trying to fix it
- Use parameterized queries for database operations
Example:
const email = req.body.email; // No validationconst { email } = req.body;
if (!email || !validator.isEmail(email)) {
throw new Error('Invalid email');
}Authentication & Password Management
Implement robust authentication to verify user identity.
Guidelines:
- Hash passwords using strong algorithms (bcrypt, Argon2, PBKDF2)
- Enforce password complexity requirements
- Implement account lockout after failed attempts
- Use multi-factor authentication (MFA) for sensitive operations
- Don't reveal if username or password was incorrect
- Rotate credentials regularly and after compromise
Example:
const hash = md5(password); // Weak hashingconst hash = await bcrypt.hash(password, 12);
const isValid = await bcrypt.compare(input, hash);Session Management
Protect session tokens and maintain secure session lifecycle.
Guidelines:
- Generate unpredictable session IDs with sufficient entropy
- Set Secure, HttpOnly, and SameSite cookie attributes
- Regenerate session ID after authentication
- Implement session timeout (idle and absolute)
- Invalidate sessions on logout
- Don't expose session IDs in URLs
Example:
res.cookie("session", sessionId); // Missing security flagsres.cookie("session", sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict',
maxAge: 3600000
});Access Control
Restrict access to resources based on user authorization.
Guidelines:
- Deny by default - require explicit grants
- Enforce access control on every request server-side
- Use role-based access control (RBAC)
- Check authorization for every resource access
- Log access control failures
- Invalidate tokens/sessions when permissions change
Example:
// Only checks authentication, not authorization
if (user) { return resource; }// Check both authentication and authorization
if (!user) throw new AuthError();
if (!user.hasPermission('resource:read')) {
throw new ForbiddenError();
}Cryptographic Practices
Use strong cryptography to protect sensitive data.
Guidelines:
- Use established cryptographic algorithms (AES-256, RSA-2048+)
- Don't create your own cryptographic functions
- Store cryptographic keys securely (HSM, secrets manager)
- Use TLS 1.2+ for data in transit
- Generate random numbers using cryptographic PRNG
- Regularly rotate encryption keys
Example:
const key = "hardcoded-secret-key"; // Hardcoded keyconst key = process.env.ENCRYPTION_KEY;
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);Error Handling & Logging
Handle errors securely without revealing sensitive information.
Guidelines:
- Don't expose stack traces or internal errors to users
- Log security events with sufficient detail
- Don't log sensitive data (passwords, tokens, PII)
- Use centralized logging and monitoring
- Implement alerts for security events
- Protect log files from tampering
Example:
res.status(500).json({ error: error.stack }); // Exposes internalslogger.error('Database error', { errorId, userId });
res.status(500).json({
error: 'An error occurred',
errorId
});Data Protection
Protect sensitive data at rest and in transit.
Guidelines:
- Classify data by sensitivity level
- Encrypt sensitive data at rest
- Use TLS for all data in transit
- Minimize data collection and retention
- Implement data backup and recovery
- Apply privacy regulations (GDPR, CCPA)
Example:
db.save({ ssn: user.ssn }); // Unencrypted PIIconst encryptedSSN = encrypt(user.ssn);
db.save({ ssn: encryptedSSN });Communication Security
Secure all network communications.
Guidelines:
- Use TLS 1.2+ for all connections
- Implement HSTS (HTTP Strict Transport Security)
- Validate TLS certificates properly
- Use secure cipher suites
- Disable deprecated protocols (SSL, TLS 1.0/1.1)
- Pin certificates for mobile apps
Example:
fetch("http://api.example.com/data"); // Insecure HTTPfetch("https://api.example.com/data", {
headers: { 'Strict-Transport-Security': 'max-age=31536000' }
});System Configuration
Secure system and application configuration.
Guidelines:
- Remove unnecessary features and files
- Change default passwords and settings
- Keep software and dependencies updated
- Use least privilege for services
- Disable directory listing
- Implement security headers (CSP, X-Frame-Options)
Example:
// No security headersapp.use(helmet()); // Adds security headers
app.use(helmet.contentSecurityPolicy({
directives: { defaultSrc: ["'self'"] }
}));Quick Security Checklist
Do
- Validate all input server-side
- Use parameterized queries
- Hash passwords with bcrypt/Argon2
- Encrypt sensitive data
- Use HTTPS everywhere
- Implement proper access control
- Log security events
- Keep dependencies updated
Don't
- Trust user input
- Concatenate SQL queries
- Store passwords in plain text
- Hardcode secrets in code
- Expose stack traces to users
- Use deprecated crypto
- Log sensitive data
- Ignore security warnings
Automate Security Checks
TigerGate automatically scans your code for OWASP vulnerabilities. Get real-time feedback on security issues before they reach production.
Start Free Security Scan