File size: 9,192 Bytes
dbf9094
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
#!/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"<html><body>Results for: {query}</body></html>"


# ============================================================
# 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'])