HIGH ssrf server sideaxumcockroachdb

Ssrf Server Side in Axum with Cockroachdb

Ssrf Server Side in Axum with Cockroachdb — how this specific combination creates or exposes the vulnerability

Server-side request forgery (SSRF) in an Axum service that uses CockroachDB can occur when user-controlled input is used to form HTTP requests or database connection parameters. Axum, a Rust web framework, does not inherently introduce SSRF, but application code that forwards requests or builds DSNs from external data can create the attack surface. CockroachDB, a distributed SQL database, does not directly cause SSRF, but its connection configuration can be influenced by attacker-controlled values if not properly constrained.

In a black-box scan, middleBrick tests unauthenticated endpoints that accept URLs or host parameters. If an endpoint accepts a URL to fetch (e.g., for webhook processing, status checks, or importing remote data) and passes it to an HTTP client without allowlisting, SSRF is possible. When the same endpoint also interacts with CockroachDB — for example, storing or retrieving connection metadata from user input — the risk expands. An attacker may leverage SSRF to reach internal CockroachDB HTTP status endpoints, the SQL shell on internal ports, or metadata services in cloud deployments, especially when network segmentation is weak.

Consider an Axum handler that accepts a target URL and a CockroachDB node host to ping:

use axum::{routing::post, Router};
use reqwest::Client;
use std::net::SocketAddr;

async unsafe fn probe_host(url: String, db_host: String) -> Result<(), ()> {
    // Risky: user-controlled URL and host used without validation
    let client = Client::new();
    let _resp = client.get(&url).send().await.map_err(|_| ())?;
    let _db_status = client.get(format!("http://{}:8080/_status", db_host)).send().await.map_err(|_| ())?;
    Ok(())
}

#[tokio::main]
async fn main() {
    let app = Router::new().route("/probe", post(probe_host));
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    axum::Server::bind(&addr).serve(app.into_make_service()).await.unwrap();
}

If the attacker controls url and db_host, they can direct requests to internal services, including CockroachDB’s admin UI on :8080 or other internal endpoints. middleBrick’s checks for SSRF include attempting to reach internal IP ranges and metadata services via submitted URLs. Even without credentials, SSRF can expose internal architecture details useful for further attacks.

Additionally, if the Axum application uses environment variables or configuration values derived from external sources to build a CockroachDB connection string, SSRF against a configuration endpoint can lead to data exposure. For example, an attacker might force the application to fetch a malicious config file that alters the DSN, leading to unintended database interactions. This is particularly relevant in deployments where configuration is fetched over HTTP and CockroachDB credentials or cluster addresses are included.

Cockroachdb-Specific Remediation in Axum — concrete code fixes

Remediation focuses on strict input validation, allowlisting, and separation of concerns. Do not allow user input to directly dictate network targets or database connection parameters. Use configuration management for CockroachDB endpoints and keep credentials out of request flow.

1. Validate and allowlist URLs

Reject any URL that does not match an expected, safe pattern. Do not attempt to probe arbitrary URLs.

use axum::{routing::post, Json};
use http::StatusCode;
use url::Url;

async fn safe_probe(Json(payload): Json) -> Result {
    let base_url = Url::parse("https://api.example.com").map_err(|e| (StatusCode::BAD_REQUEST, e.to_string()))?;
    if !payload.url.starts_with(&base_url) {
        return Err((StatusCode::BAD_REQUEST, "Invalid target".to_string()));
    }
    // Safe: proceed with controlled request
    Ok(Json(serde_json::json!({ "status": "ok" })))
}

#[derive(serde::Deserialize)]
struct ProbePayload {
    url: String,
}

2. Do not accept database host/port from users

Define CockroachDB connection details in configuration or environment variables. If dynamic routing is required, use an allowlist of known cluster identifiers mapped to fixed endpoints.

use cockroachdb_rs::Connection;
use std::env;

fn get_db_connection() -> Connection {
    let database_url = env::var("COCKROACH_URL").expect("COCKROACH_URL must be set");
    Connection::connect(&database_url).expect("Failed to connect to CockroachDB")
}

3. Use a proxy for outbound requests

If outbound HTTP is necessary, route through an internal proxy with strict policies rather than allowing arbitrary destinations from user input. This limits SSRF impact and keeps database connectivity separate from user-facing request flows.

4. Principle of least privilege for database permissions

Ensure the CockroachDB user used by Axum has minimal required permissions. Even if SSRF occurs, the attacker’s lateral movement is limited.

-- Example CockroachDB role with restricted privileges
CREATE USER web_app WITH PASSWORD 'secure_password';
GRANT SELECT, INSERT ON TABLE public.records TO web_app;
REVOKE ALL ON DATABASE cluster_admin FROM web_app;

Frequently Asked Questions

Can SSRF in Axum lead to CockroachDB compromise even without credentials?
Yes. SSRF can expose internal endpoints such as CockroachDB’s HTTP status port or administrative interfaces, revealing cluster topology and configuration details that may aid further attacks.
Does middleBrick test for SSRF when scanning Axum services connected to CockroachDB?
Yes. middleBrick runs parallel security checks including SSRF, testing unauthenticated endpoints that accept external URLs or host inputs to detect potential internal network reachability.