Table of Contents
Security Principles
- Defense in Depth: Multiple layers of security
- Least Privilege: Minimum permissions needed
- Fail Securely: Default to deny on errors
- Don't Trust Input: Validate everything
- Keep It Simple: Complexity breeds vulnerabilities
Input Validation
SQL Injection Prevention
❌ Vulnerable
query = f"SELECT * FROM users WHERE id = {user_input}"✅ Secure (Parameterized)
cursor.execute("SELECT * FROM users WHERE id = %s", (user_input,))XSS Prevention
❌ Vulnerable
<p>Hello, {{ user_name }}</p>✅ Secure (Escaped)
<p>Hello, {{ user_name | escape }}</p>Path Traversal Prevention
❌ Vulnerable
file_path = f"/uploads/{filename}" # ../../../etc/passwd✅ Secure
import os
safe_name = os.path.basename(filename)
file_path = os.path.join("/uploads", safe_name)Output Encoding
| HTML Context | HTML entity encoding |
| JavaScript | JavaScript encoding |
| URL | URL/percent encoding |
| CSS | CSS encoding |
| SQL | Parameterized queries |
Authentication & Sessions
Password Storage
❌ Never
password_hash = md5(password) # Weak!
password_hash = sha256(password) # No salt!✅ Correct
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt())Session Security
// Secure session cookie settings
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: true, // HTTPS only
httpOnly: true, // No JavaScript access
sameSite: 'strict',// CSRF protection
maxAge: 3600000 // 1 hour
}
}));
Cryptography
Dos and Don'ts
- ✅ Use established libraries (libsodium, OpenSSL)
- ✅ AES-256-GCM for symmetric encryption
- ✅ RSA-OAEP or ECDH for key exchange
- ❌ Never invent your own crypto
- ❌ Never hardcode keys
- ❌ Avoid ECB mode
Error Handling
❌ Leaks Information
except Exception as e:
return f"Error: {str(e)}" # Exposes stack trace!✅ Generic Error
except Exception as e:
logger.error(f"Database error: {e}")
return "An error occurred. Please try again."Updated: December 2024