#!/usr/bin/env python3 """ VULNERABLE CODE SAMPLES - FOR TESTING ONLY ========================================== This file contains intentionally vulnerable code patterns. DO NOT use this code in production! This file demonstrates various security vulnerabilities that the security checker should detect. Think of it as a "patient" for our security "doctor" to diagnose. """ import os import pickle import hashlib import random import subprocess import sqlite3 import yaml from flask import Flask, request, redirect app = Flask(__name__) # ============================================================ # VULNERABILITY 1: SQL Injection # Analogy: Like leaving your house key under the doormat # ============================================================ def get_user_unsafe(username): """VULNERABLE: User input directly concatenated into SQL query.""" conn = sqlite3.connect('users.db') cursor = conn.cursor() # BAD: String formatting in SQL query query = f"SELECT * FROM users WHERE username = '{username}'" cursor.execute(query) return cursor.fetchone() def search_products_unsafe(search_term): """VULNERABLE: Another SQL injection example.""" conn = sqlite3.connect('products.db') cursor = conn.cursor() # BAD: f-string in execute cursor.execute(f"SELECT * FROM products WHERE name LIKE '%{search_term}%'") return cursor.fetchall() # ============================================================ # VULNERABILITY 2: Command Injection # Analogy: Like letting a stranger operate your computer # ============================================================ def ping_server_unsafe(hostname): """VULNERABLE: User input passed directly to shell command.""" # BAD: os.system with user input os.system(f"ping -c 1 {hostname}") def convert_file_unsafe(filename): """VULNERABLE: subprocess with shell=True and user input.""" # BAD: shell=True with f-string subprocess.call(f"convert {filename} output.pdf", shell=True) # ============================================================ # VULNERABILITY 3: Hardcoded Credentials # Analogy: Writing your PIN on your credit card # ============================================================ # BAD: Passwords in source code DATABASE_PASSWORD = "SuperSecret123!" API_KEY = "sk-1234567890abcdef1234567890abcdef" SECRET_TOKEN = "my_very_secret_token_12345" def connect_to_database(): """VULNERABLE: Hardcoded password.""" password = "AnotherHardcodedPass123" return f"mysql://user:{password}@localhost/db" # ============================================================ # VULNERABILITY 4: Weak Password Hashing # Analogy: Using a paper lock instead of a steel one # ============================================================ def hash_password_weak(password): """VULNERABLE: Using MD5 for password hashing.""" # BAD: MD5 is cryptographically broken return hashlib.md5(password.encode()).hexdigest() def verify_password_sha1(password, stored_hash): """VULNERABLE: Using SHA1 for password hashing.""" # BAD: SHA1 is not suitable for passwords return hashlib.sha1(password.encode()).hexdigest() == stored_hash # ============================================================ # VULNERABILITY 5: Insecure Deserialization # Analogy: Opening a package without checking what's inside # ============================================================ def load_user_data_unsafe(data): """VULNERABLE: Deserializing untrusted data with pickle.""" # BAD: pickle.loads on user-provided data return pickle.loads(data) def load_config_unsafe(config_file): """VULNERABLE: yaml.load without SafeLoader.""" with open(config_file) as f: # BAD: yaml.load without specifying Loader return yaml.load(f) # ============================================================ # VULNERABILITY 6: Insecure Random Number Generation # Analogy: Using predictable dice in a casino # ============================================================ def generate_token_unsafe(): """VULNERABLE: Using random module for security tokens.""" # BAD: random.random is not cryptographically secure return ''.join([chr(int(random.random() * 26) + 65) for _ in range(32)]) def generate_session_id_unsafe(): """VULNERABLE: Using random.randint for session IDs.""" # BAD: Predictable session IDs return str(random.randint(100000, 999999)) # ============================================================ # VULNERABILITY 7: Path Traversal # Analogy: A visitor who can access any room in your house # ============================================================ def read_file_unsafe(filename): """VULNERABLE: User input used directly in file path.""" # BAD: No path validation with open(f"/uploads/{filename}") as f: return f.read() def serve_image_unsafe(image_name): """VULNERABLE: Path traversal in file operations.""" # BAD: Could access ../../etc/passwd path = "/images/" + image_name with open(path, 'rb') as f: return f.read() # ============================================================ # VULNERABILITY 8: XSS (Cross-Site Scripting) # Analogy: Letting someone put their own signs in your store # ============================================================ @app.route('/search') def search_results_unsafe(): """VULNERABLE: Reflected XSS vulnerability.""" query = request.args.get('q', '') # BAD: User input rendered directly in HTML return f"Results for: {query}" # ============================================================ # VULNERABILITY 9: Open Redirect # Analogy: A sign that sends visitors anywhere they want # ============================================================ @app.route('/redirect') def redirect_unsafe(): """VULNERABLE: Open redirect vulnerability.""" # BAD: Unvalidated redirect URL next_url = request.args.get('next') return redirect(next_url) # ============================================================ # VULNERABILITY 10: Debug Mode Enabled # Analogy: Leaving your diary open on the coffee table # ============================================================ # BAD: Debug mode in production DEBUG = True FLASK_DEBUG = True if __name__ == '__main__': # BAD: Debug mode enabled app.run(debug=True, host='0.0.0.0') # ============================================================ # VULNERABILITY 11: SSL Verification Disabled # Analogy: Accepting any ID without checking if it's real # ============================================================ import requests def fetch_data_unsafe(url): """VULNERABLE: SSL verification disabled.""" # BAD: verify=False allows MITM attacks response = requests.get(url, verify=False) return response.text # ============================================================ # VULNERABILITY 12: Sensitive Data in Logs # Analogy: Announcing credit card numbers over a loudspeaker # ============================================================ import logging def log_login_unsafe(username, password): """VULNERABLE: Logging sensitive information.""" # BAD: Password logged in plaintext logging.info(f"Login attempt: username={username}, password={password}") def log_payment_unsafe(card_number, cvv): """VULNERABLE: Logging credit card information.""" # BAD: Credit card data in logs print(f"Processing payment: card={card_number}, cvv={cvv}") # ============================================================ # VULNERABILITY 13: Hardcoded Encryption Key # Analogy: Using the same lock combination as everyone else # ============================================================ # BAD: Hardcoded encryption key ENCRYPTION_KEY = b'ThisIsASecretKey1234567890123456' AES_IV = b'InitializationV!' def encrypt_unsafe(data): """VULNERABLE: Using hardcoded encryption key.""" from Crypto.Cipher import AES # BAD: Hardcoded key used directly key = b'MySuperSecretKey1234567890123456' cipher = AES.new(key, AES.MODE_CBC, AES_IV) return cipher.encrypt(data) # ============================================================ # VULNERABILITY 14: CORS Wildcard # Analogy: Allowing anyone to pick up your mail # ============================================================ @app.after_request def add_cors_headers(response): """VULNERABLE: Permissive CORS configuration.""" # BAD: Wildcard CORS allows any origin response.headers['Access-Control-Allow-Origin'] = '*' response.headers['Access-Control-Allow-Methods'] = '*' return response # ============================================================ # VULNERABILITY 15: JWT Without Verification # Analogy: Accepting any badge without checking if it's real # ============================================================ import jwt def decode_token_unsafe(token): """VULNERABLE: JWT decoded without verification.""" # BAD: verify=False bypasses signature check return jwt.decode(token, verify=False) def decode_with_none_alg(token): """VULNERABLE: Allowing 'none' algorithm.""" # BAD: 'none' algorithm is insecure return jwt.decode(token, algorithms=['none'])