oxidecomputer / oxidecomputer/omicron

Audit all use of `push_sql` + `format!` within `nexus/db-queries` to prevent SQL Injection

Open
#4,144 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

database nexus
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:

https://github.com/oxidecomputer/omicron/blob/9a1f6bc5da1efed13dabbe14ec5066002cfd0851/nexus/db-queries/src/db/queries/vpc.rs#L85-L99

Using this interface correctly means:

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.