System Security: Authentication, Authorization, and Common Vulnerabilities
Learn essential security concepts including authentication methods, authorization patterns, common vulnerabilities (OWASP Top 10), and secure system design.
Security as a Design Constraint
Security isn't an afterthought — it must be baked into the architecture from the start. A breach can destroy user trust and incur massive costs.
Defense in depth: Never rely on a single security measure. Layer your defenses so that if one fails, others protect you.
Authentication vs Authorization
Authentication (Who are you?)
Verifying user identity.
Authorization (What can you do?)
Verifying permissions.
Authentication Methods
Password-Based Authentication
# Never store passwords in plain text!
# Always hash with salt
import hashlib
import secrets
def hash_password(password, salt=None):
if salt is None:
salt = secrets.token_hex(32)
hash_value = hashlib.pbkdf2_hmac(
'sha256',
password.encode(),
salt.encode(),
100000
)
return f"{salt}${hash_value.hex()}"
def verify_password(password, stored_hash):
salt, hash_value = stored_hash.split('$')
return hash_password(password, salt) == stored_hash
Never use MD5 or SHA-1 for passwords. They're too fast (vulnerable to brute force). Use bcrypt, scrypt, or Argon2 with appropriate work factors.
Multi-Factor Authentication (MFA)
Token-Based Authentication
JWT Structure
{
"header": {
"alg": "RS256",
"typ": "JWT"
},
"payload": {
"sub": "user123",
"role": "admin",
"exp": 1704067200,
"iat": 1704063600
},
"signature": "..."
}
Authorization Patterns
Role-Based Access Control (RBAC)
Attribute-Based Access Control (ABAC)
{
"condition": {
"resource": "document-123",
"action": "read",
"subject": {
"department": "engineering",
"clearance": "secret"
},
"environment": {
"time": "2024-01-15T09:00:00Z"
}
}
}
OAuth 2.0 Flow
OWASP Top 10 Vulnerabilities
1. Broken Access Control
# Vulnerable: User can access other users' data
@app.route('/orders/<order_id>')
def get_order(order_id):
return db.query(f"SELECT * FROM orders WHERE id = {order_id}")
# Fixed: Verify ownership
@app.route('/orders/<order_id>')
@require_auth
def get_order(order_id):
order = db.query(
"SELECT * FROM orders WHERE id = ? AND user_id = ?",
order_id, current_user.id
)
if not order:
abort(404)
return order
2. Cryptographic Failures
# Vulnerable: Weak encryption
cipher = Fernet.generate_key() # Using default key
# Fixed: Use strong keys, proper modes
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
key = os.urandom(32) # 256-bit key
aesgcm = AESGCM(key)
3. Injection
# Vulnerable: SQL injection
query = f"SELECT * FROM users WHERE email = '{email}'"
# Fixed: Parameterized queries
query = "SELECT * FROM users WHERE email = ?"
db.execute(query, (email,))
4. Insecure Design
| Threat | Mitigation |
|---|---|
| Credential stuffing | Rate limiting, MFA |
| Brute force | Account lockout, CAPTCHA |
| Excessive data exposure | Return only needed fields |
5. Security Misconfiguration
- Disable debug mode in production
- Use secure defaults
- Regular security updates
- Minimal attack surface (disable unused features)
6. Sensitive Data Exposure
Secure System Design
Secrets Management
Input Validation
from pydantic import BaseModel, validator
class UserInput(BaseModel):
email: str
age: int
@validator('email')
def validate_email(cls, v):
if '@' not in v:
raise ValueError('Invalid email')
return v.lower()
@validator('age')
def validate_age(cls, v):
if v < 0 or v > 150:
raise ValueError('Invalid age')
return v
Rate Limiting
from functools import wraps
from redis import Redis
redis = Redis()
def rate_limit(max_requests, window_seconds):
def decorator(f):
@wraps(f)
def wrapper(user_id, *args, **kwargs):
key = f"rate_limit:{user_id}"
current = redis.get(key)
if current and int(current) > max_requests:
return "Rate limit exceeded", 429
pipe = redis.pipeline()
pipe.incr(key)
pipe.expire(key, window_seconds)
pipe.execute()
return f(user_id, *args, **kwargs)
return wrapper
return decorator
Security Checklist
| Category | Checklist Item |
|---|---|
| Authentication | Password hashing (bcrypt/Argon2) |
| Authentication | MFA for sensitive operations |
| Authorization | Principle of least privilege |
| Data | Encrypt sensitive data at rest |
| Data | Use TLS for data in transit |
| Input | Validate and sanitize all inputs |
| Dependencies | Regular dependency audits |
| Logging | Log security events, not sensitive data |
What to Remember for Interviews
- Never trust user input: Always validate and sanitize
- Hash passwords: Never store plain text, use bcrypt/Argon2
- Defense in depth: Layer your security controls
- Least privilege: Grant minimum necessary permissions
- OWASP Top 10: Know the common vulnerabilities and mitigations
Practice: Review the OWASP Top 10 and understand how each vulnerability works and how to prevent it. If asked about security in an interview, demonstrate practical knowledge, not just buzzwords.