oxidecomputer / oxidecomputer/omicron
Audit all use of `push_sql` + `format!` within `nexus/db-queries` to prevent SQL Injection
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 572
- Forks
- 97
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 96
Description
Diesel uses the 'bind' method (See SqlQuery::bind for one example, but there are other variations) to ensure that variables within SQL statements are escaped property, avoiding SQL injection.
This is generally done automatically -- for a query like:
let data = animals
.select(species)
.filter(name.eq("; DROP TABLE USERS; "))
.first::<String>(connection)?;
The argument to .eq is AsExpression, which treats this argument as data to be escaped before placing it in the query.
From the Diesel docs:
Implementations of [AsExpression] will generally...
... Indicate that the type has data which will be sent separately from the query. This is generally referred as a “bind parameter”. Types which implement ToSql will generally implement AsExpression this way.
That works through the ToSql trait, which basically encapsulates "how to shove a value into the protocol which gets sent to the DB".
For vanilla Diesel, this is fine, and this usage should not be susceptible to injection attacks -- preventing this is the responsibility of those ToSql and AsExpression traits.
However, nexus/db-queries has some spots where it constructs more complicated queries, relying on traits like QueryFragment to construct SQL queries from strings. Here's one such example:
Using this interface correctly means:
- All identifiers should be added with
push_identifier - All bind parameters should be added with
push_bind_param - All FULLY STATIC SQL should be added with
push_sql.
Note that "fully static SQL" is not actually enforced by the type system -- if you wanted to add a string constructed via format! here, you could.
- Audit all usage of
push_sql - Write property tests to confirm that SQL injection via APIs is unlikely
- Document this property somewhere?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in nexus/db-queries, especially nexus/db-queries/src/db/queries/vpc.rs lines 85-99, and audit every use of push_sql together with format!. Check that dynamic identifiers and values use the Diesel binding interfaces described in the issue. Done means the remaining unsafe-looking construction paths are addressed, property tests are added, and the SQL-injection safety property is documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- databases, security
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100