Analyze a vulnerable web application, identify security issues, write a report, and fix the vulnerabilities.

Setup: Create the vulnerable application.

/tmp/vuln-app/app.py:
```python
from flask import Flask, request, render_template_string, redirect, session
import sqlite3
import os
import subprocess
import pickle
import base64

app = Flask(__name__)
app.secret_key = "super_secret_key_123"

def get_db():
    db = sqlite3.connect('/tmp/vuln-app/users.db')
    db.execute('''CREATE TABLE IF NOT EXISTS users
                  (id INTEGER PRIMARY KEY, username TEXT, password TEXT, role TEXT)''')
    db.execute('''CREATE TABLE IF NOT EXISTS posts
                  (id INTEGER PRIMARY KEY, user_id INTEGER, title TEXT, content TEXT)''')
    # Seed data
    try:
        db.execute("INSERT INTO users VALUES (1, 'admin', 'admin123', 'admin')")
        db.execute("INSERT INTO users VALUES (2, 'user1', 'password', 'user')")
        db.execute("INSERT INTO posts VALUES (1, 1, 'Welcome', 'Hello World')")
        db.commit()
    except:
        pass
    return db

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        db = get_db()
        # SQL Injection vulnerability
        query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
        user = db.execute(query).fetchone()
        if user:
            session['user_id'] = user[0]
            session['username'] = user[1]
            session['role'] = user[3]
            return redirect('/dashboard')
        return "Login failed"
    return '<form method="post"><input name="username"><input name="password" type="password"><button>Login</button></form>'

@app.route('/dashboard')
def dashboard():
    if 'username' not in session:
        return redirect('/login')
    # XSS vulnerability - reflected
    name = request.args.get('name', session['username'])
    # Template injection vulnerability
    template = f"<h1>Welcome {name}</h1><p>Role: {session.get('role', 'user')}</p>"
    return render_template_string(template)

@app.route('/search')
def search():
    q = request.args.get('q', '')
    db = get_db()
    # SQL Injection vulnerability
    results = db.execute(f"SELECT * FROM posts WHERE title LIKE '%{q}%'").fetchall()
    # XSS vulnerability - stored/reflected
    output = f"<h2>Results for: {q}</h2><ul>"
    for r in results:
        output += f"<li>{r[2]}: {r[3]}</li>"
    output += "</ul>"
    return output

@app.route('/exec')
def exec_cmd():
    # Command injection vulnerability
    cmd = request.args.get('cmd', 'echo hello')
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
    return f"<pre>{result.stdout}</pre>"

@app.route('/profile', methods=['GET', 'POST'])
def profile():
    if request.method == 'POST':
        # Insecure deserialization vulnerability
        data = request.form.get('data', '')
        profile_data = pickle.loads(base64.b64decode(data))
        return f"Profile updated: {profile_data}"
    return '<form method="post"><input name="data"><button>Update</button></form>'

@app.route('/file')
def read_file():
    # Path traversal vulnerability
    filename = request.args.get('name', 'readme.txt')
    filepath = os.path.join('/tmp/vuln-app/files', filename)
    try:
        with open(filepath) as f:
            return f"<pre>{f.read()}</pre>"
    except:
        return "File not found"

if __name__ == '__main__':
    os.makedirs('/tmp/vuln-app/files', exist_ok=True)
    with open('/tmp/vuln-app/files/readme.txt', 'w') as f:
        f.write('Welcome to the app!')
    app.run(debug=True)
```

Requirements:

1. Create /tmp/vuln-app/vulnerability_report.json with an array of findings, each containing:
   - cwe_id (e.g., "CWE-89")
   - vulnerability_type (e.g., "SQL Injection")
   - severity: "critical", "high", "medium", or "low"
   - location: file and line number(s)
   - description: what the vulnerability is
   - exploit_example: how it could be exploited
   - fix_description: how to fix it

2. You must identify at least these vulnerabilities:
   - SQL Injection (CWE-89) - in /login and /search
   - XSS / Template Injection (CWE-79) - in /dashboard and /search
   - Command Injection (CWE-78) - in /exec
   - Insecure Deserialization (CWE-502) - in /profile
   - Path Traversal (CWE-22) - in /file
   - Hardcoded Credentials (CWE-798) - secret_key

3. Create /tmp/vuln-app/app_fixed.py that fixes ALL identified vulnerabilities:
   - Use parameterized queries for SQL
   - Use proper template escaping / Markup.escape()
   - Remove or restrict command execution endpoint
   - Replace pickle with JSON deserialization
   - Sanitize file paths (os.path.realpath, check prefix)
   - Use environment variable or random bytes for secret_key

4. Create /tmp/vuln-app/test_security.py that verifies each fix:
   - Test SQL injection attempt returns no data
   - Test XSS payload is escaped in output
   - Test command injection is blocked
   - Test path traversal is blocked
   - Test deserialization rejects pickle

After completing:
- /tmp/vuln-app/vulnerability_report.json has at least 6 findings
- /tmp/vuln-app/app_fixed.py exists and has no obvious vulnerabilities
- python3 -c "import json; r=json.load(open('/tmp/vuln-app/vulnerability_report.json')); assert len(r)>=6, f'Only {len(r)} findings'"
- cd /tmp/vuln-app && python3 -m pytest test_security.py -v passes