"""
Lesson 25 — Exercise 6: SAST (Static Analysis) Practice
=========================================================
Goal: Read code, find vulnerabilities, propose fixes — WITHOUT
ever running the code.

This is exactly what SAST tools do automatically. Doing it by hand
trains the same instincts.

For each snippet:
  1. Identify the vulnerability category
  2. Describe how an attacker would exploit it
  3. Rewrite the code securely
"""


import sqlite3


# ═══════════════════════════════════════════════════════════════
# SNIPPET 1
# ═══════════════════════════════════════════════════════════════
def login(username, password):
    conn = sqlite3.connect('users.db')
    cursor = conn.cursor()
    query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'"
    cursor.execute(query)
    return cursor.fetchone()

# Vulnerability category:
# Sample malicious input:
# Fix (write the corrected code as a comment or below):


# ═══════════════════════════════════════════════════════════════
# SNIPPET 2
# ═══════════════════════════════════════════════════════════════
API_KEY = "sk_live_4f8e2a9c7b1d6e3f5a8c0b9d2e7f4a1c"

def charge_card(amount):
    print(f"Charging ${amount} using key {API_KEY}")
    # ... pretend this calls the payment API

# Vulnerability category:
# Why is this dangerous even before the code reaches production?
# Fix:


# ═══════════════════════════════════════════════════════════════
# SNIPPET 3
# ═══════════════════════════════════════════════════════════════
def render_comment_to_page(user_comment):
    html = f"<div class='comment'>{user_comment}</div>"
    return html

# Vulnerability category:
# Sample malicious input:
# Fix:


# ═══════════════════════════════════════════════════════════════
# SNIPPET 4 — input validation
# ═══════════════════════════════════════════════════════════════
def transfer_funds(amount_str, from_account, to_account):
    amount = float(amount_str)
    print(f"Transferring ${amount} from {from_account} to {to_account}")
    # ... rest of transfer

# List 3 abnormal inputs that could break or abuse this:
#   1.
#   2.
#   3.
# How would you validate amount_str before converting?


# ═══════════════════════════════════════════════════════════════
# SNIPPET 5 — error handling
# ═══════════════════════════════════════════════════════════════
def get_user_profile(user_id):
    try:
        conn = sqlite3.connect('users.db')
        cursor = conn.cursor()
        cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
        return cursor.fetchone()
    except Exception as e:
        return str(e)   # ← bad idea

# This has TWO problems. Find both:
#   1.
#   2.
# Fix:


# ═══════════════════════════════════════════════════════════════
# REFLECTION
# ═══════════════════════════════════════════════════════════════
# 1. Did you find every vulnerability without running the file? Good — that's SAST.
# 2. Which one took you the longest to spot? Why?
# 3. Could a DAST tool (runs the live app) have found these too?
#    Which ones can ONLY be found by reading the source?


if __name__ == '__main__':
    # The whole point of this exercise is NOT to execute.
    # Read, annotate, propose fixes. That's static analysis.
    print("This file is for reading, not running.")
