CodeRaptor
Back to Guides
Security Guide

OWASP Secure Coding Practices Guide

Master OWASP secure coding practices to prevent vulnerabilities and build secure applications. Learn how to protect against the OWASP Top 10 threats and common attack vectors.

Reading time: 15 min
Level: Intermediate
Updated: March 2025

Why Secure Coding Matters

Security vulnerabilities can lead to data breaches, financial losses, and reputational damage. According to recent studies, 84% of security breaches involve application-layer attacks, making secure coding practices essential for every developer.

This guide covers the most critical security practices based on the OWASP Top 10 and industry best practices. Each section includes practical examples and code snippets you can implement immediately.

Core Security Practices

1. Input Validation & Sanitization

Always validate and sanitize user input to prevent injection attacks. Never trust data from users, APIs, or any external source.

Bad Practice

// Vulnerable to SQL injection
const query = `SELECT * FROM users WHERE email = '${email}'`;
db.query(query);

// Vulnerable to XSS
element.innerHTML = userInput;

Good Practice

// Use parameterized queries
const query = 'SELECT * FROM users WHERE email = ?';
db.query(query, [email]);

// Sanitize output
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);

// Validate input format
function isValidEmail(email) {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}

2. Strong Authentication

Implement secure authentication with proper password hashing, session management, and multi-factor authentication.

Bad Practice

// Storing passwords in plain text
user.password = password;

// Weak password requirements
if (password.length >= 6) { /* accept */ }

// Using MD5/SHA1 for passwords
const hash = md5(password);

Good Practice

import bcrypt from 'bcrypt';

// Hash passwords with bcrypt
const saltRounds = 12;
const hashedPassword = await bcrypt.hash(password, saltRounds);

// Strong password validation
function validatePassword(password) {
  const minLength = 12;
  const hasUpperCase = /[A-Z]/.test(password);
  const hasLowerCase = /[a-z]/.test(password);
  const hasNumbers = /\d/.test(password);
  const hasSpecialChar = /[!@#$%^&*]/.test(password);

  return password.length >= minLength &&
         hasUpperCase && hasLowerCase &&
         hasNumbers && hasSpecialChar;
}

// Implement rate limiting
const loginAttempts = new Map();
function checkRateLimit(ip) {
  const attempts = loginAttempts.get(ip) || 0;
  if (attempts >= 5) {
    throw new Error('Too many login attempts');
  }
  loginAttempts.set(ip, attempts + 1);
}

3. Secure Data Storage

Encrypt sensitive data at rest and in transit. Use environment variables for secrets, never hardcode them.

Bad Practice

// Hardcoded secrets
const API_KEY = 'sk_live_1234567890abcdef';
const DB_PASSWORD = 'MyPassword123';

// Storing sensitive data in plain text
await db.save({ ssn: '123-45-6789' });

Good Practice

// Use environment variables
const API_KEY = process.env.API_KEY;
const DB_PASSWORD = process.env.DB_PASSWORD;

// Encrypt sensitive data
import { encrypt, decrypt } from './encryption';

async function saveSensitiveData(data) {
  const encryptedSSN = encrypt(data.ssn, process.env.ENCRYPTION_KEY);
  await db.save({ ssn: encryptedSSN });
}

// Use HTTPS for all communications
const options = {
  cert: fs.readFileSync('cert.pem'),
  key: fs.readFileSync('key.pem')
};
https.createServer(options, app);

4. Implement Proper Access Control

Enforce principle of least privilege and implement role-based access control (RBAC).

Implementation Example

// Middleware for role-based access control
function requireRole(allowedRoles) {
  return (req, res, next) => {
    if (!req.user) {
      return res.status(401).json({ error: 'Unauthorized' });
    }

    if (!allowedRoles.includes(req.user.role)) {
      return res.status(403).json({ error: 'Forbidden' });
    }

    next();
  };
}

// Usage
app.delete('/api/users/:id',
  requireRole(['admin']),
  async (req, res) => {
    // Only admins can delete users
    await deleteUser(req.params.id);
    res.json({ success: true });
  }
);

// Verify ownership
async function requireOwnership(req, res, next) {
  const resource = await getResource(req.params.id);
  if (resource.userId !== req.user.id && req.user.role !== 'admin') {
    return res.status(403).json({ error: 'Access denied' });
  }
  next();
}

5. Security Logging & Monitoring

Implement comprehensive logging for security events and monitor for suspicious activity.

Security Event Logging

import winston from 'winston';

const securityLogger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.File({
      filename: 'security.log'
    })
  ]
});

// Log security events
function logSecurityEvent(event, user, metadata) {
  securityLogger.info({
    timestamp: new Date().toISOString(),
    event,
    userId: user?.id,
    ip: metadata.ip,
    userAgent: metadata.userAgent,
    ...metadata
  });
}

// Usage
app.post('/login', async (req, res) => {
  try {
    const user = await authenticate(req.body);
    logSecurityEvent('LOGIN_SUCCESS', user, {
      ip: req.ip,
      userAgent: req.get('user-agent')
    });
    res.json({ token: generateToken(user) });
  } catch (error) {
    logSecurityEvent('LOGIN_FAILURE', null, {
      ip: req.ip,
      email: req.body.email,
      reason: error.message
    });
    res.status(401).json({ error: 'Invalid credentials' });
  }
});

Security Checklist

Code Security

  • Validate all user inputs
  • Use parameterized queries
  • Implement CSRF protection
  • Set secure HTTP headers
  • Use Content Security Policy
  • Enable HTTPS everywhere

Authentication & Access

  • Hash passwords with bcrypt
  • Implement MFA
  • Use secure session management
  • Apply rate limiting
  • Enforce strong passwords
  • Implement RBAC

Data Protection

  • Encrypt sensitive data
  • Use environment variables
  • Implement data retention policies
  • Secure file uploads
  • Sanitize user output
  • Regular security backups

Monitoring & Response

  • Log security events
  • Monitor for anomalies
  • Set up alerts
  • Regular security audits
  • Keep dependencies updated
  • Have incident response plan

Security Tools & Resources

OWASP Top 10

The definitive list of web application security risks

Learn more →

Security Headers

Scan your site for security headers

Learn more →

npm audit

Check for vulnerabilities in dependencies

Learn more →

Snyk

Developer security platform

Learn more →

SonarQube

Code quality and security analysis

Learn more →

CodeRaptor

AI-powered security scanning

Learn more →

Automate Security Reviews with CodeRaptor

Let CodeRaptor automatically scan your code for security vulnerabilities. Catch issues before they reach production.

Start Free Trial