Security & Reliability

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.

22 min readsecurityauthenticationauthorizationOAuthJWTOWASP

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

python
# 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

json
{
  "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)

json
{
  "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

python
# 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

python
# 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

python
# 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

ThreatMitigation
Credential stuffingRate limiting, MFA
Brute forceAccount lockout, CAPTCHA
Excessive data exposureReturn 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

python
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

python
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

CategoryChecklist Item
AuthenticationPassword hashing (bcrypt/Argon2)
AuthenticationMFA for sensitive operations
AuthorizationPrinciple of least privilege
DataEncrypt sensitive data at rest
DataUse TLS for data in transit
InputValidate and sanitize all inputs
DependenciesRegular dependency audits
LoggingLog security events, not sensitive data

What to Remember for Interviews

  1. Never trust user input: Always validate and sanitize
  2. Hash passwords: Never store plain text, use bcrypt/Argon2
  3. Defense in depth: Layer your security controls
  4. Least privilege: Grant minimum necessary permissions
  5. 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.