Skip to content

Rust: New Query rust/cleartext-storage-database #20137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

geoffw0
Copy link
Contributor

@geoffw0 geoffw0 commented Jul 29, 2025

New query rust/cleartext-storage-database for "Cleartext storage of sensitive information in a database".

Work in progress. Needs:

  • docs and examples.
  • change note(s).
  • add security-severity value.
  • testing / refinement with MRVA.
  • DCA run.
  • docs review.
  • code review.

@geoffw0 geoffw0 added the Rust Pull requests that update Rust code label Jul 29, 2025
@geoffw0 geoffw0 changed the title Rust: New Query Rust: New Query rust/cleartext-storage-database Jul 29, 2025
Copy link
Contributor

QHelp previews:

rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.qhelp

Cleartext storage of sensitive information in a database

Sensitive information that is stored unencrypted in a database is accessible to an attacker who gains access to that database. For example, the information could be accessed by any process or user in a rooted device, or exposed through another vulnerability.

Recommendation

Either encrypt the entire database, or ensure that each piece of sensitive information is encrypted before being stored. In general, decrypt sensitive information only at the point where it is necessary for it to be used in cleartext. Avoid storing sensitive information at all if you do not need to keep it.

Example

The following example stores sensitive information into a database without encryption, using the SQLx library:

let query = "INSERT INTO PAYMENTDETAILS(ID, CARDNUM) VALUES(?, ?)";
let result = sqlx::query(query)
	.bind(id)
	.bind(credit_card_number) // BAD: Cleartext storage of sensitive data in the database
	.execute(pool)
	.await?;

This is insecure because the sensitive data is stored in cleartext, making it accessible to anyone with access to the database.

To fix this, we can either encrypt the entire database or encrypt just the sensitive data before it is stored. Take care to select a secure modern encryption algorithm and put suitable key management practices into place. In the following example, we have encrypted the sensitive data using 256-bit AES before storing it in the database:

fn encrypt(text: String, encryption_key: &aes_gcm::Key<Aes256Gcm>) -> String {
    // encrypt text -> ciphertext
    let cipher = Aes256Gcm::new(&encryption_key);
    let nonce = Aes256Gcm::generate_nonce(&mut OsRng);
    let ciphertext = cipher.encrypt(&nonce, text.as_ref()).unwrap();

    // append (nonce, ciphertext)
    let mut combined = nonce.to_vec();
    combined.extend(ciphertext);

    // encode to base64 string
    BASE64_STANDARD.encode(combined)
}

fn decrypt(data: String, encryption_key: &aes_gcm::Key<Aes256Gcm>) -> String {
    let cipher = Aes256Gcm::new(&encryption_key);

    // decode base64 string
    let decoded = BASE64_STANDARD.decode(data).unwrap();

    // split into (nonce, ciphertext)
    let nonce_size = <Aes256Gcm as AeadCore>::NonceSize::to_usize();
    let (nonce, ciphertext) = decoded.split_at(nonce_size);

    // decrypt ciphertext -> plaintext
    let plaintext = cipher.decrypt(nonce.into(), ciphertext).unwrap();
    String::from_utf8(plaintext).unwrap()
}

...

let encryption_key = Aes256Gcm::generate_key(OsRng);

...

let query = "INSERT INTO PAYMENTDETAILS(ID, CARDNUM) VALUES(?, ?)";
let result = sqlx::query(query)
	.bind(id)
	.bind(encrypt(credit_card_number, &encryption_key)) // GOOD: Encrypted storage of sensitive data in the database
	.execute(pool)
	.await?;

References

@geoffw0 geoffw0 marked this pull request as ready for review August 4, 2025 17:26
@geoffw0 geoffw0 requested a review from a team as a code owner August 4, 2025 17:26
@Copilot Copilot AI review requested due to automatic review settings August 4, 2025 17:26
Copilot

This comment was marked as outdated.

@geoffw0 geoffw0 added the ready-for-doc-review This PR requires and is ready for review from the GitHub docs team. label Aug 4, 2025
saritai
saritai previously approved these changes Aug 4, 2025
Copy link
Contributor

@saritai saritai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@geoffw0 Just took a look - from the docs side, it looks good! 🚀

@Copilot Copilot AI review requested due to automatic review settings August 5, 2025 19:26
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a new security query rust/cleartext-storage-database to detect cleartext storage of sensitive information in databases. The query identifies when sensitive data (such as SSNs, phone numbers, credit card numbers) is stored unencrypted in database operations, which can expose this data to attackers who gain database access.

Key changes include:

  • Implementation of the new security query with data flow analysis
  • Comprehensive test coverage for various database operations (SQLx, rusqlite)
  • Documentation and examples showing proper encryption practices

Reviewed Changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated no comments.

Show a summary per file
File Description
rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql Main query implementation using taint tracking to detect sensitive data flow to database sinks
rust/ql/lib/codeql/rust/security/CleartextStorageDatabaseExtensions.qll Extension module defining sources, sinks, and barriers for the cleartext storage analysis
rust/ql/lib/codeql/rust/frameworks/sqlx.model.yml Model definitions for SQLx framework database operations as sinks
rust/ql/test/query-tests/security/CWE-312/test_storage.rs Comprehensive test cases covering various database operations and scenarios
rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.qhelp Documentation explaining the vulnerability and providing secure coding examples

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation ready-for-doc-review This PR requires and is ready for review from the GitHub docs team. Rust Pull requests that update Rust code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants