Skip to content

fix(findings): use parameterized queries to prevent SQL injection in list - #481

Merged
ajianaz merged 2 commits into
developfrom
fix/findings-sql-injection
Aug 4, 2026
Merged

fix(findings): use parameterized queries to prevent SQL injection in list#481
ajianaz merged 2 commits into
developfrom
fix/findings-sql-injection

Conversation

@ajianaz

@ajianaz ajianaz commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

What

Fixes SQL injection vulnerabilities in cora findings list command.

Vulnerable code (before)

Two filters interpolated user input directly into SQL via format!():

// --severity flag
format!("f.severity = '{}'", s.to_uppercase())

// --file flag
format!("f.file_path LIKE '%{}%'", f.replace('"', "'"))

The f.replace('"', "'") only escaped double-quotes — not single-quotes,
which are the SQL string delimiter. This made it completely ineffective.

Attack vectors

Flag Input Resulting SQL
--severity critical' OR 1=1 -- WHERE f.severity = 'CRITICAL' OR 1=1 --'
--file '; DROP TABLE findings; -- LIKE '%'; DROP TABLE findings; --%'

Fix

Use ? placeholders + rusqlite::params! — the same pattern already used
by dismiss() and reopen() in the same file.

Why

Cora is a security tool. Shipping SQL injection in its own CLI undermines
credibility. While exploitability requires local access, this is a
defense-in-depth issue and a best-practice violation.

Testing

  • cargo test --bin cora — 782 pass, 0 fail
  • cargo clippy -- -D warnings — clean
  • cargo fmt --all — clean
  • Manual: cora findings list --severity "critical' OR 1=1 --" now returns
    empty results (no matching severity) instead of leaking all findings

ajianaz added 2 commits August 4, 2026 18:04
…list

The severity and file filters in list_findings() interpolated user input
directly into SQL strings via format!():

  format!("f.severity = '{}'", s.to_uppercase())
  format!("f.file_path LIKE '%{}%'", f.replace('"', "'"))

This allowed SQL injection through --severity or --file flags. The
f.replace('"', "'") only escaped double-quotes, not the single-quote
SQL string delimiter, making it ineffective.

Fix: build WHERE clause with ? placeholders and pass user input via
rusqlite::params!, matching the pattern already used by dismiss() and
reopen().
SQL injection:
The severity and file filters in list_findings() interpolated user
input directly into SQL strings via format!().

Flaky test:
data_dir tests mutated CODECORA_HOME without synchronization, causing
intermittent failures when tests ran in parallel.
@ajianaz
ajianaz merged commit 4c4e291 into develop Aug 4, 2026
13 checks passed
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