Api Key Exposure in Axum with Mssql
Api Key Exposure in Axum with Mssql — how this specific combination creates or exposes the vulnerability
When building web services in Axum that connect to Microsoft SQL Server (Mssql), developers often embed database credentials or connection strings directly in source code or configuration files. This pattern creates an Api Key Exposure vulnerability because the keys are static and can be extracted from compiled artifacts, version control history, or runtime logs. In Axum handlers, if a connection string containing an API key or database credential is constructed dynamically using string formatting or concatenation, the key may be inadvertently exposed through error messages, debug endpoints, or logs. For example, logging the full connection string during request processing can reveal the key to anyone with access to application logs.
Mssql-specific risks arise because connection strings often include sensitive parameters such as Password, User ID, and Persist Security Info. If these parameters are set to true and the connection string is logged or returned in error responses, an attacker can harvest credentials and pivot to the database. Axum middleware that captures and logs errors without filtering sensitive fields can amplify this exposure. Additionally, if the application uses integrated security but still passes credentials via connection strings to Mssql, those credentials become part of the application’s runtime environment and may be exposed through memory dumps or profiling tools.
The combination of Axum’s asynchronous request handling and Mssql’s authentication mechanisms means that improperly managed secrets can be leaked through timing differences or verbose error outputs. For instance, a handler that constructs a connection string per request using hardcoded credentials can leak the key in stack traces when SQL authentication fails. This violates the principle of least privilege and can lead to unauthorized data access or modification. Using environment variables or secure vaults is recommended, but if those secrets are then concatenated into Mssql connection strings without proper sanitization, the exposure risk remains.
Moreover, OpenAPI or Swagger specifications generated for Axum endpoints might inadvertently document example connection parameters, exposing expected key names or formats. When combined with Mssql, this can provide attackers with hints about credential structure. The scanner’s checks for Data Exposure and Unsafe Consumption are designed to detect such patterns by correlating runtime behavior with specification definitions, including $ref resolutions that reveal how secrets flow through the API surface.
To mitigate, Axum applications should avoid embedding keys in code and instead use runtime injection via secure configuration providers. When connecting to Mssql, use integrated security where possible and ensure that connection strings are built from secure sources without logging sensitive components. The middleBrick CLI can scan your Axum endpoints to identify exposed keys in error handling or documentation, while the GitHub Action can enforce thresholds in CI/CD pipelines to prevent deployments that introduce such exposures.
Mssql-Specific Remediation in Axum — concrete code fixes
Remediation focuses on removing hardcoded credentials from Axum handlers and ensuring Mssql connection strings are constructed securely. Below are concrete, syntactically correct examples for Axum using Rust and the tiberius crate for Mssql connectivity.
1. Use environment variables and a secure configuration struct instead of hardcoded keys:
use axum::Router;
use std::env;
use tiberius::Config;
use tokio::net::TcpStream;
use tokio_util::compat::TokioAsyncWriteCompatExt;
#[derive(Clone)]
struct AppState {
db_config: DbConfig,
}
struct DbConfig {
host: String,
port: u16,
database: String,
username: String,
password: String,
}
impl AppState {
fn from_env() -> Result {
Ok(Self {
db_config: DbConfig {
host: env::var("DB_HOST").map_err(|_| "missing DB_HOST")?,
port: env::var("DB_PORT")
.map_err(|_| "missing DB_PORT")?
.parse()
.map_err(|_| "invalid DB_PORT")?,
database: env::var("DB_NAME").map_err(|_| "missing DB_NAME")?,
username: env::var("DB_USER").map_err(|_| "missing DB_USER")?,
password: env::var("DB_PASSWORD").map_err(|_| "missing DB_PASSWORD")?,
},
})
}
fn build_connection_string(&self) -> String {
format!(
"server={};port={};database={};user id={};password={};",
self.db_config.host,
self.db_config.port,
self.db_config.database,
self.db_config.username,
self.db_config.password
)
}
}
async fn connect_to_mssql(state: &AppState) -> Result<(), Box> {
let conn_str = state.build_connection_string();
let tcp = TcpStream::connect(&format!("{}:{}", state.db_config.host, state.db_config.port)).await?;
tcp.set_nodelay(true)?;
let mut client = Config::from_ado_string(&conn_str)
.map_err(|e| format!("config error: {:?}", e))?
.connect(tcp.compat_write())
.await?;
// Use client for queries
Ok(())
}
2. Avoid logging or serializing connection strings. Ensure that error handlers do not include sensitive data:
use axum::{
error_handling::HandleErrorLayer,
response::IntoResponse,
routing::get,
Router,
};
use std::convert::Infallible;
use tracing::error;
async fn health_check() -> impl IntoResponse {
"OK"
}
async fn fallback_handler(err: axum::BoxError) -> impl IntoResponse {
// Log without exposing credentials
error!(error = %err, "Request failed");
(axum::http::StatusCode::INTERNAL_SERVER_ERROR, "Internal error")
}
fn app(state: AppState) -> Router {
Router::new()
.route("/health", get(health_check))
.layer(HandleErrorLayer::new(fallback_handler))
}
3. In OpenAPI documentation, avoid including sensitive parameters in examples. Use references to security schemes instead:
// openapi.yaml
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
paths:
/users:
get:
summary: Get users
security:
- bearerAuth: []
responses:
'200':
description: Success
These practices reduce the risk of Api Key Exposure when using Axum with Mssql. The middleBrick CLI can validate that no credentials appear in source or spec files, and the GitHub Action can enforce these checks before merging.