HIGH dns rebindingactixhmac signatures

Dns Rebinding in Actix with Hmac Signatures

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

DNS Rebinding is an application-layer attack that manipulates DNS responses to make a victim’s browser connect an initially trusted hostname to an arbitrary IP address, often within the attacker’s infrastructure. In Actix-based services that rely on HMAC Signatures for request authentication, this interaction can bypass origin validation when the application uses the hostname as part of the trust boundary without additional verification.

Consider an Actix-web service that validates incoming requests using an HMAC signature derived from a shared secret and selected headers (e.g., X-API-Key and Host). If the service resolves the hostname once during initial connection setup and then trusts that hostname for the duration of the session or for subsequent internal checks, an attacker can exploit DNS rebinding to change the IP address while keeping the original hostname constant. The browser continues to send requests with the same origin header, but the backend may incorrectly associate the new IP with the trusted hostname, especially when CORS or IP-based allowances are applied naively.

During a middleBrick scan, unauthenticated checks can detect whether Actix endpoints are vulnerable to DNS Rebinding by observing whether the application treats the Host header as authoritative after initial resolution and whether HMAC validation is applied inconsistently across requests. If the HMAC is computed over the Host header but the service does not re-validate the hostname against a strict allowlist on each request, an attacker can bypass intended access controls. This becomes a security finding under input validation and property authorization checks, because the effective identity of the endpoint is not verified on every request.

For example, an attacker may first cause the victim to resolve api.trusted.example.com to a benign IP. Then, via a malicious DNS response, the attacker rebinds the name to an attacker-controlled server while the victim’s browser maintains the same origin. If the Actix service uses the HMAC signature to authorize requests based on the original hostname without recomputing or validating the endpoint’s current IP or zone, the malicious server can issue signed requests that the backend treats as legitimate, leading to unauthorized actions or data exposure.

To detect this during a scan, middleBrick runs checks that cross-reference OpenAPI/Swagger specifications (with full $ref resolution) against runtime behavior, looking for missing hostname verification and inconsistent HMAC usage. The tool examines whether security checks such as Authentication and Property Authorization are applied uniformly and whether findings should be mapped to frameworks like OWASP API Top 10 or SOC2 controls. Remediation guidance is provided with severity and actionable steps rather than attempting automatic fixes.

Hmac Signatures-Specific Remediation in Actix — concrete code fixes

To mitigate DNS Rebinding risks in Actix when using HMAC Signatures, ensure that hostname validation is performed independently of DNS resolution and that HMAC verification is applied consistently on every request. Do not rely on the Host header alone for authorization; instead, validate the target hostname or IP against an explicit allowlist and recompute HMAC verification per request.

Below is a concrete, working example in Rust using Actix-web and the hmac crate. The code demonstrates secure HMAC verification with strict hostname validation before processing a request.

use actix_web::{web, HttpRequest, HttpResponse, Result};
use hmac::{Hmac, Mac};
use sha2::Sha256;
use std::collections::HashSet;

// Define a type alias for HMAC-SHA256
 type HmacSha256 = Hmac;

// Allowed hostnames to prevent DNS rebinding
const ALLOWED_HOSTS: &[&str] = &["api.trusted.example.com"];

fn verify_hmac_signature(req: &HttpRequest, body: &[u8]) -> Result {
    // Retrieve headers needed for HMAC verification
    let maybe_signature = req.headers().get("X-API-Signature");
    let maybe_api_key = req.headers().get("X-API-Key");

    let signature = match maybe_signature {
        Some(val) => val.to_str().map_err(|_| actix_web::error::ErrorBadRequest("Invalid signature header"))?,
        None => return Ok(false),
    };

    let api_key = match maybe_api_key {
        Some(val) => val.to_str().map_err(|_| actix_web::error::ErrorBadRequest("Invalid API key header"))?,
        None => return Ok(false),
    };

    // Compute HMAC over method, path, and body using the API key as the secret
    let mut mac = HmacSha256::new_from_slice(api_key.as_bytes())
        .map_err(|_| actix_web::error::ErrorInternalServerError("HMAC initialization failed"))?;
    let method = req.method().as_str();
    let path = req.path();
    mac.update(method.as_bytes());
    mac.update(path.as_bytes());
    mac.update(body);

    // Decode the provided signature (assumed to be hex-encoded)
    let computed_signature = hex::decode(signature)
        .map_err(|_| actix_web::error::ErrorBadRequest("Invalid signature encoding"))?;

    // Verify in constant time
    if mac.verify_slice(&computed_signature).is_ok() {
        Ok(true)
    } else {
        Ok(false)
    }
}

async fn protected_handler(req: HttpRequest, body: web::Bytes) -> Result {
    // Validate hostname against allowlist
    let host = match req.headers().get("Host") {
        Some(h) => h.to_str().unwrap_or(""),
        None => return Ok(HttpResponse::BadRequest().body("Missing Host header")),
    };

    if !ALLOWED_HOSTS.contains(&host) {
        return Ok(HttpResponse::Forbidden().body("Hostname not allowed"));
    }

    // Verify HMAC signature
    let is_valid = verify_hmac_signature(&req, &body)?;
    if !is_valid {
        return Ok(HttpResponse::Unauthorized().body("Invalid HMAC signature"));
    }

    // Proceed with business logic
    Ok(HttpResponse::Ok().body("Request authenticated"))
}

In this example, the service does not trust the resolved IP address and re-validates the hostname on every request using an allowlist. The HMAC is computed over the HTTP method, path, and body, ensuring that any modification to the request changes the signature. By combining strict hostname validation with per-request HMAC verification, the risk of DNS Rebinding bypassing authentication is substantially reduced.

When using middleBrick, you can scan your Actix endpoints to confirm that Host header validation and HMAC checks are consistently applied. The tool provides prioritized findings with severity and remediation guidance, helping you address issues such as missing hostname verification or inconsistent signature usage. Plans such as the Pro tier include continuous monitoring and GitHub Action integration to catch regressions in CI/CD pipelines.

Frequently Asked Questions

Can DNS Rebinding bypass HMAC authentication in Actix services?
Yes, if the service trusts the Host header or other identifiers after initial resolution and does not re-validate the hostname on each request, DNS Rebinding can bypass HMAC-based authentication. Mitigate this by validating the hostname against an allowlist on every request and including non-rebindable identifiers in the HMAC computation.
How does middleBrick detect DNS Rebinding risks in Actix APIs using Hmac Signatures?
middleBrick runs unauthenticated checks that analyze how the Actix service uses the Host header and whether HMAC verification is applied consistently across requests. The scan cross-references your OpenAPI specification (with full \$ref resolution) against runtime behavior to identify missing hostname validation or inconsistent signature usage, producing findings with severity and remediation guidance.