Skip to content

🛡️ Sentinel: [CRITICAL] Fix SQL injection in sqliteColumnExists#86

Open
mattjoyce wants to merge 1 commit into
mainfrom
sentinel-fix-sqlite-sql-injection-14103200951403298888
Open

🛡️ Sentinel: [CRITICAL] Fix SQL injection in sqliteColumnExists#86
mattjoyce wants to merge 1 commit into
mainfrom
sentinel-fix-sqlite-sql-injection-14103200951403298888

Conversation

@mattjoyce
Copy link
Copy Markdown
Owner

🚨 Severity: CRITICAL
💡 Vulnerability: The sqliteColumnExists function in internal/storage/sqlite.go was constructing a SQLite PRAGMA table_info(%s) query using fmt.Sprintf directly with the table name. Since the table name is essentially a parameter, this poses a SQL injection risk if the table name originates from user or external input.
🎯 Impact: Exploitation could allow arbitrary SQL execution depending on how the PRAGMA query parses injected statements.
🔧 Fix: Replaced the PRAGMA statement with the safer table-valued function equivalent: SELECT ... FROM pragma_table_info(?), passing the table name securely as a parameter.
✅ Verification: Ran go test -v ./internal/storage/... (updating golden outputs as necessary) and ran the full suite via go test -v ./... -short to ensure everything functions properly without regressions. Also verified .jules/sentinel.md entry was added.


PR created automatically by Jules for task 14103200951403298888 started by @mattjoyce

…terized pragma_table_info

- Migrates from string interpolation (`fmt.Sprintf("PRAGMA table_info(%s);", table)`) to parameterized table-valued function (`SELECT ... FROM pragma_table_info(?)`).
- Adds Sentinel journal entry.
- Updates query explain golden tests.

Co-authored-by: mattjoyce <278869+mattjoyce@users.noreply.github.com>
mattjoyce added a commit that referenced this pull request Jun 6, 2026
…te_dir, no duplicate uid (#84)

Open map (any number of rows); two tiers are the documented posture, not a cap.
uid<=0 rejected so a worker can never be root; duplicate uid rejected as false
isolation (#87 would chown both state_dirs to one owner). Adds workers + WorkerConf
to config.schema.json (authoring aid, ADR §11). Absent/empty map is valid here —
the capability/refuse boot gate is #86.
mattjoyce added a commit that referenced this pull request Jun 6, 2026
Boot gate (cmd/ductile/runtime.go): capability-to-drop x workers-configured must
agree or the daemon refuses to start; service.unconfined is the explicit, loud
override. Pure decision (evaluateBootGate) + a platform capability probe (root, or
Linux CAP_SETUID/SETGID via /proc/self/status). The dispatcher drops only when the
gate says enforce (WithPrivsepEnforce), so dev/override paths skip resolution.

A refused drop is now a typed ErrWorkerDropFailed with its own plugin.drop_failed
event, distinct from a missing binary, and classified TERMINAL (never retried).
Verified on macOS; wall + refuse paths to re-verify on the Dell.
mattjoyce added a commit that referenced this pull request Jun 6, 2026
TestHasDropCapabilityAsRoot asserts hasDropCapability()==true under root (Dell /
privileged container); skips on non-root dev. Full #86 enforce half now proven on
privileged Linux: wall still bites under the enforce gate, capability probe reads
true, drop-failed is typed + terminal.
mattjoyce added a commit that referenced this pull request Jun 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant