Sensitive information in source code - Credentials
Need
Removal of database credentials from source code
Context
• Usage of Rust 1.75+ for building application services
• Usage of the actix-web crate for handling HTTP requests
• Usage of the sqlx crate with PostgreSQL for database access
Description
1. Non compliant code
use actix_web::{web, App, HttpServer};
use sqlx::postgres::{PgConnectOptions, PgPoolOptions};
async fn run() -> std::io::Result<()> {
// The database password ships with the source and the binary
let options = PgConnectOptions::new()
.host("db.internal")
.username("admin")...The `run` function below connects to PostgreSQL with `PgConnectOptions` and passes the password `SuperSecret123` as a string literal. Everyone who can read the repository, including former employees, contractors and any tool with access to it, knows the database password. The value stays in the version control history after it is removed, and it is embedded in the compiled binary and in container images, where anyone who pulls the image can extract it. If the database is reachable, that is enough to read or modify all the data the account can access. The password cannot be rotated without a new release, and the same value tends to be reused across environments. Connection strings with an embedded user and password, for PostgreSQL, Redis or MongoDB, have the same problem.
2. Steps
• Remove passwords from connection strings passed to `PgPoolOptions::connect`, `PgPool::connect`, Diesel `establish`, `redis::Client::open` and `mongodb::Client::with_uri_str`.
• Load database credentials at runtime from a secrets manager, a mounted secret file or an environment variable.
• Fail at startup when the credential is missing or empty instead of falling back to a default.
• Rotate every password that was committed, since it remains in the repository history and in built images.
• Use a different account and password for each environment and service.
• Add a secret scanner to the CI pipeline to block new credentials in source code.
3. Secure code example
use actix_web::{web, App, HttpServer};
use sqlx::postgres::{PgConnectOptions, PgPoolOptions, PgSslMode};
use std::fs;
use std::io::{Error, ErrorKind};
const PASSWORD_FILE: &str = "/run/secrets/db_password";
async fn run() -> std::io::Result<()> {...The corrected function builds the connection with `PgConnectOptions` and reads the password at runtime from `/run/secrets/db_password`, the file where Docker and Kubernetes mount secrets. The orchestrator fills that file from a secrets manager, so the password never appears in the source, the binary or the image, and it can be rotated by updating the secret and restarting the service. Reading from a file keeps the value out of environment variables, which are easier to leak through process listings, crash reports and debug endpoints. The function trims the trailing newline that secret files often contain, and fails at startup when the file is missing or empty. The connection also requires TLS with `PgSslMode::VerifyFull`, which verifies the server certificate and host name, so the credentials are only sent to the real database.