Harden SQLCipher PRAGMA key against SQL injection #45

Open
opened 2026-04-10 17:20:14 -07:00 by pyr0ball · 0 comments
Owner

Bug

circuitforge_core/db/base.py line 26 uses raw string interpolation to set the SQLCipher database key:

conn.execute(f"PRAGMA key='{key}'")

If key contains a single quote or other SQL metacharacters, this is a SQL injection vector. All products that pass a per-user key to get_connection() in cloud mode are affected (Peregrine, Kiwi, Snipe).

Fix

SQLCipher 4.x supports parameterized PRAGMA:

# Option A: parameterized (SQLCipher 4+)
conn.execute("PRAGMA key=?", (key,))

# Option B: hex-encoded raw key (works on all SQLCipher versions)
# Only applicable when key is bytes, not a passphrase
if isinstance(key, bytes):
    conn.execute(f"PRAGMA key=\"x'{key.hex()}'\"")
else:
    conn.execute("PRAGMA key=?", (key,))

Confirm which SQLCipher version is pinned in requirements before choosing the approach. Add a test with a key containing ' to regression-cover this.

Affected files

  • circuitforge_core/db/base.py line 26

Priority

Fix before any product ships cloud user data encryption. Low exploitability in current deployments (key comes from env, not user input) but the pattern is unsafe as the codebase grows.

Labels

security, bug

## Bug `circuitforge_core/db/base.py` line 26 uses raw string interpolation to set the SQLCipher database key: ```python conn.execute(f"PRAGMA key='{key}'") ``` If `key` contains a single quote or other SQL metacharacters, this is a SQL injection vector. All products that pass a per-user key to `get_connection()` in cloud mode are affected (Peregrine, Kiwi, Snipe). ## Fix SQLCipher 4.x supports parameterized PRAGMA: ```python # Option A: parameterized (SQLCipher 4+) conn.execute("PRAGMA key=?", (key,)) # Option B: hex-encoded raw key (works on all SQLCipher versions) # Only applicable when key is bytes, not a passphrase if isinstance(key, bytes): conn.execute(f"PRAGMA key=\"x'{key.hex()}'\"") else: conn.execute("PRAGMA key=?", (key,)) ``` Confirm which SQLCipher version is pinned in requirements before choosing the approach. Add a test with a key containing `'` to regression-cover this. ## Affected files - `circuitforge_core/db/base.py` line 26 ## Priority Fix before any product ships cloud user data encryption. Low exploitability in current deployments (key comes from env, not user input) but the pattern is unsafe as the codebase grows. ## Labels `security`, `bug`
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Circuit-Forge/circuitforge-core#45
No description provided.