🛡️ Sentinel: [CRITICAL] Fix SQL Injection in PRAGMA table_info#107
🛡️ Sentinel: [CRITICAL] Fix SQL Injection in PRAGMA table_info#107mattjoyce wants to merge 1 commit into
Conversation
Co-authored-by: mattjoyce <278869+mattjoyce@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
ductile | e421dc3 | Commit Preview URL Branch Preview URL |
May 28 2026, 11:46 AM |
📝 WalkthroughWalkthroughThis PR eliminates a SQL injection vulnerability in SQLite column-existence checking by replacing string-interpolated ChangesSQL Injection Fix for Column Existence Check
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.jules/sentinel.md:
- Line 1: The file's first line uses a level-2 heading ("## 2024-05-18 -
Parameterized Table-Valued Functions") which triggers markdownlint MD041; change
that first line to a top-level heading by replacing "##" with "#" so the file
begins with "# 2024-05-18 - Parameterized Table-Valued Functions" (ensure no
blank lines precede it).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 9ecdbba9-fbe3-4a52-8d9d-38531d4dec14
📒 Files selected for processing (2)
.jules/sentinel.mdinternal/storage/sqlite.go
| @@ -0,0 +1,5 @@ | |||
| ## 2024-05-18 - Parameterized Table-Valued Functions | |||
There was a problem hiding this comment.
Use a top-level heading on the first line.
Line 1 starts with ##, which triggers markdownlint MD041 and can fail lint gates for docs.
Suggested fix
-## 2024-05-18 - Parameterized Table-Valued Functions
+# 2024-05-18 - Parameterized Table-Valued Functions📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ## 2024-05-18 - Parameterized Table-Valued Functions | |
| # 2024-05-18 - Parameterized Table-Valued Functions |
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.jules/sentinel.md at line 1, The file's first line uses a level-2 heading
("## 2024-05-18 - Parameterized Table-Valued Functions") which triggers
markdownlint MD041; change that first line to a top-level heading by replacing
"##" with "#" so the file begins with "# 2024-05-18 - Parameterized Table-Valued
Functions" (ensure no blank lines precede it).
…vault fail-open ductile-admin source diligence found the secret_ref-for-plugins scheme cannot work: PluginConf has no secret_ref (only webhook/relay do); the only plugin secret path is the spawn-time stdin secrets map, needing principal==plugin-name (kebab, no normalization) AND the plugin reading that map. #107 = the dev workstream to make first-party plugins vault-native (the real secret-holder enforce path). #108 = vault compose is fail-OPEN on an unknown principal (silent no-secret) — out of step with privsep fail-closed spine.
…locate, secrets not a config reconcile Relocating plugin code to /opt invalidates attestation → #93 fail-safe downgrades to untrusted until plugin lock re-records fingerprints (witnessed live). Plugin secrets need the #107 vault-native workstream (PluginConf has no secret_ref; principals must be kebab; vault compose fail-open #108). migrate-everything splits 3 ways: keyless-now / secret-holders-after-#107 / unconfinable-admin-#106.
…substitution Tested live on discord_notify: config check rejects webhook_url_ref as not satisfying required webhook_url; runtime "No webhook_url configured". Vault→plugin is ONLY the stdin secrets map → per-plugin kebab-rename + code change to read secrets[...]. Not a config tweak.
Enforced data-plane gateway live on :8081: vault carried, 5 keyless integrations enforced+attested on default(1001), config/plugin lock, admission re-enabled, all wall-bites pass. #93 downgrade proven live. Remaining carded as dev workstreams: #107 (HEAVY, secret-holders), #106 (admin instance), #108 (vault fail-open), #105 (FHS package). Old --user decommission deferred until #106+#107 land.
…l (+ schema vault_file) The vault rejects non-kebab principal names; #107 would otherwise need every secret-holding plugin RENAMED to kebab (breaking config/pipeline refs). New plugins.<name>.vault_principal lets a snake_case plugin (discord_notify) compose its secrets under a kebab principal (discord-notify) WITHOUT a rename; attestation still uses the plugin name. This is the repo-side enabler — the remaining #107 work (each plugin reading the stdin secrets map) lives in the external plugin repos. Also added the missing secrets.vault_file to the schema (drift: live key, would fail strict validate). +test.
…live) discord_notify proved end-to-end: webhook from the encrypted vault over stdin, uid 1001, attested, requires_vault fail-closed. Recorded the reusable 5-step recipe on card #107 (read stdin secrets map, manifest required:[], kebab principal, vault_principal+requires_vault, relocate+lock) + a runbook pointer. NOTE: the discord_notify plugin code change is in the external ductile-plugins repo.
github_repo_sync et al are vault-native + ready but exit 127 under enforce: uv run --script needs uv on PATH + writable HOME/cache and walks config up-tree into the 0700 cwd. Affects the 4 git plugins; disabled for now. Fix: account-friendly uv (UV_CACHE_DIR/HOME + cwd off 0700) or de-uv to plain python3. Found during the #107 push.
…on + fail-closed proven live Recipe step 1 generalized: name the vault secret via a config key (salt_secret/token_secret) so a shared base plugin stays reusable across instances. Status: discord_notify + ap_canary vault-native + live (B form: snake instance + vault_principal + requires_vault); fail-closed PROVEN live (bogus principal → refused spawn). Plugin code @ ductile-plugins a1934e5. git/uv plugins → #109.
🚨 Severity: CRITICAL
💡 Vulnerability: Used
fmt.Sprintfto constructPRAGMA table_infoquery with dynamic table names, allowing potential SQL injection.🎯 Impact: Could allow arbitrary SQL execution if the table parameter can be controlled by an attacker.
🔧 Fix: Replaced
PRAGMAstatement with SQLite's table-valued functionpragma_table_info(?)which fully supports parameterized queries. This ensures all input is properly sanitized. Added journal entry documenting learning.✅ Verification: Ran
make testlocally to verify changes, confirming existing test suite functions correctly and the logic handlessql.ErrNoRowsprecisely as before.PR created automatically by Jules for task 4686737539554573183 started by @mattjoyce
Summary by CodeRabbit