BlogSecurity

OWASP Secure Coding Practices

A comprehensive guide to OWASP secure coding guidelines. Learn how to write secure code and prevent common vulnerabilities.

22 min readUpdated December 2025

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

OWASP Top 10: Most critical web app security risks
ASVS: Application Security Verification Standard
SAMM: Software Assurance Maturity Model
Cheat Sheets: Quick reference security guides

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:

Bad:
const email = req.body.email; // No validation
Good:
const { 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:

Bad:
const hash = md5(password); // Weak hashing
Good:
const 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:

Bad:
res.cookie("session", sessionId); // Missing security flags
Good:
res.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:

Bad:
// Only checks authentication, not authorization
if (user) { return resource; }
Good:
// 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:

Bad:
const key = "hardcoded-secret-key"; // Hardcoded key
Good:
const 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:

Bad:
res.status(500).json({ error: error.stack }); // Exposes internals
Good:
logger.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:

Bad:
db.save({ ssn: user.ssn }); // Unencrypted PII
Good:
const 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:

Bad:
fetch("http://api.example.com/data"); // Insecure HTTP
Good:
fetch("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:

Bad:
// No security headers
Good:
app.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