HIGH dangling dnsactixhmac signatures

Dangling Dns in Actix with Hmac Signatures

Dangling Dns in Actix with Hmac Signatures — how this specific combination creates or exposes the vulnerability

A dangling DNS configuration in an Actix web service becomes particularly risky when endpoints are protected only by HMAC signatures without additional host validation. In this combination, an attacker who can control DNS records for a domain that your Actix service trusts may be able to redirect the service’s outbound HTTP client to a malicious host while the HMAC verification still passes.

HMAC signatures in Actix are commonly implemented by signing request data (such as a payload, timestamp, or nonce) with a shared secret and including the signature in a header. If the service uses a hardcoded or environment-derived secret and validates the signature but does not strictly validate the server identity (e.g., via certificate pinning or strict hostname checks), an attacker can serve a valid response from a rogue server that the DNS record now points to. The signature checks may succeed because the attacker can replay or forward the signed request to the malicious host, especially if the signing logic does not include the target hostname as part of the signed string.

Consider an Actix middleware that signs requests using HMAC-SHA256 over method, path, and body, and then forwards the request to an upstream service resolved via DNS. If the upstream hostname is resolved at runtime and the DNS entry is swapped to point to an attacker-controlled server, the client may unknowingly send sensitive data to the attacker. The HMAC verification on the server side (if verification is one-way) might still pass because the attacker can reflect or manipulate the request path and body to match the signature, especially when the signing scope excludes the hostname or when the service trusts the resolved IP implicitly.

This scenario maps to the BOLA/IDOR and Data Exposure checks in middleBrick’s 12 security checks, where insecure use of identifiers and lack of strict transport binding can lead to unauthorized data access. middleBrick’s scan would flag such misconfigurations under the Unauthenticated attack surface tests, highlighting the risk when DNS resolution is dynamic and host verification is weak.

To detect this class of issue, middleBrick’s LLM/AI Security module can also probe for endpoints that lack hostname binding in signed requests, looking for patterns where the signature does not cover the target host. Without including the hostname (and optionally the port and scheme) in the signed string, the HMAC does not protect against a redirect to a malicious endpoint even if the payload remains unchanged.

Hmac Signatures-Specific Remediation in Actix — concrete code fixes

Remediation focuses on ensuring that the hostname (and scheme and port) are part of the signed string and that the client verifies the server’s identity using certificate pinning or strict hostname validation. In Actix, you can enforce this by customizing the request signing logic and the HTTP client used for outbound calls.

Below is a concrete example of HMAC signing in Actix that includes the method, hostname, port, path, and body. The signature is computed over a canonical string that binds the request to a specific target host and port, making it invalid if the DNS redirects to another host.

use hmac::{Hmac, Mac};
use sha2::Sha256;
use actix_web::{web, HttpRequest, HttpResponse, Result};
use reqwest::Client;
use std::time::{SystemTime, UNIX_EPOCH};

type HmacSha256 = Hmac<Sha256>;

async fn signed_request(target_url: &str, body: &str, secret: &[u8]) -> Result<HttpResponse> {
let url = target_url.parse::<reqwest::Url>().map_err(|e| {
actix_web::error::ErrorBadRequest(format!("Invalid URL: {}", e))
})?;
let host = url.host_str().ok_or_else(|| {
actix_web::error::ErrorBadRequest("Missing host")
})?;
let port = url.port_or_known_default().unwrap_or(443);
let method = "POST";
let path = url.path();
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs()
.to_string();

// Canonical string includes method, host, port, path, timestamp, and body
let canonical = format!("{}\n{}:{}\n{}\n{}\n{}\n{}", method, host, port, path, timestamp, body);
let mut mac = HmacSha256::new_from_slice(secret).map_err(|e| {
actix_web::error::ErrorInternalServerError(format!("HMAC error: {}", e))
})?;
mac.update(canonical.as_bytes());
let result = mac.finalize();
let signature = result.into_bytes();
let signature_hex = hex::encode(signature);

let client = Client::new();
let response = client
.post(target_url)
.header("X-API-Timestamp", timestamp)
.header("X-API-Signature", signature_hex)
.body(body.to_string())
.send()
.await?;

// Optionally verify hostname against a pinned certificate or known list
// For example, enforce that host matches an expected value
if host != "api.example.com" {
return Err(actix_web::error::ErrorForbidden("Unexpected host"));
}

Ok(response)
}

In this example, the canonical string includes the host and port, so if DNS is compromised and the request is redirected to a different host, the signature verification on the server side will fail (assuming the server also validates the host). Additionally, the client validates the hostname before sending the request, adding a layer of protection against DNS-based redirection.

You can integrate this function into an Actix route or middleware. For production use, manage the secret via secure configuration and rotate it periodically. Combine this approach with middleware that rejects requests to unexpected hosts and uses HTTPS with certificate pinning where possible to further reduce the attack surface.

middleBrick’s dashboard and CLI can help verify that your endpoints include host binding in signed requests and flag configurations where the signature scope is too narrow, which is a common finding in scans related to BOLA/IDOR and Data Exposure.

Frequently Asked Questions

Why does including the hostname in the HMAC signature protect against dangling DNS in Actix?
Including the hostname (and port) in the signed canonical string binds the signature to a specific target host. If DNS is compromised and the request is redirected to a malicious host, the signature will not match because the hostname in the request differs from the one used to generate the signature, causing verification to fail.
Can middleBrick detect missing hostname binding in HMAC-signed Actix endpoints?
Yes, middleBrick’s scans include checks that examine whether signed requests include host identity in the signed scope. Findings are surfaced in the Unauthenticated and Data Exposure checks, with remediation guidance to bind signatures to hostname, port, and scheme.