Missing Authentication in Actix with Hmac Signatures
Missing Authentication in Actix with Hmac Signatures
Actix is a widely used Rust web framework where developers often choose HMAC signatures to authenticate HTTP requests. The vulnerability arises when endpoints that should be protected rely only on signature verification but do not enforce authentication checks for every request. In such cases, an attacker can send requests with valid HMAC headers derived from leaked or weak secrets, or send requests without any signature at all if the verification middleware is inconsistently applied.
Consider an Actix web service that uses HMAC-SHA256 to sign a subset of endpoints while leaving others open. If the developer fails to consistently apply authentication guards, the unauthenticated attack surface expands. For example, a health check or status endpoint might skip middleware, allowing an unauthenticated caller to learn whether the service is running or to probe for misconfigurations. Even when signatures are used, if the application does not require authentication for all sensitive routes, an attacker can exploit the missing authentication gap to invoke business logic that should be restricted.
During a middleBrick scan, which tests the unauthenticated attack surface in black-box mode, such inconsistencies are detected. The scanner checks whether endpoints that accept HMAC-signed requests also require authentication for unauthenticated calls. It looks for routes that lack guards, or where the signature verification passes but no downstream authorization is enforced. This can lead to unauthorized data access or operations, even when HMAC is present, because the missing authentication control bypasses intended access restrictions.
Real-world attack patterns mirror this class of risk. For instance, an attacker might send GET requests to administrative or data-export endpoints that mistakenly skip authentication checks, relying on obscurity rather than strict controls. In scenarios where HMAC is used for idempotency or replay protection but not paired with mandatory authentication, the system remains vulnerable to unauthorized invocation. Findings from a scan will highlight routes with missing authentication requirements and provide remediation guidance focused on ensuring that every sensitive path enforces authentication consistently, regardless of the presence of HMAC signatures.
Hmac Signatures-Specific Remediation in Actix
To remediate missing authentication in Actix when HMAC signatures are in use, ensure that every route that handles sensitive operations requires authentication, and that signature verification is applied consistently. Do not rely on signature presence alone; combine it with explicit authentication checks so that missing or malformed credentials are rejected even if the signature is valid.
Below are concrete, working examples for an Actix application using HMAC-SHA256. The first example shows a middleware guard that validates the HMAC signature and also enforces authentication. The second example demonstrates how to apply this guard selectively to routes that require protection, while keeping public routes accessible.
use actix_web::{web, App, HttpResponse, HttpServer, Responder, dev::ServiceRequest, Error};
use actix_web::http::header::HeaderValue;
use actix_web::middleware::Next;
use hmac::{Hmac, Mac};
use sha2::Sha256;
use std::collections::HashMap;
type HmacSha256 = Hmac;
async fn verify_hmac(
req: ServiceRequest,
credentials: web::Data>,
mut payload: web::Payload,
next: Next<'_>,
) -> Result {
let path = req.path();
let method = req.method().clone();
let headers = req.headers();
let timestamp = headers.get("X-Timestamp")
.ok_or_else(|| actix_web::error::ErrorUnauthorized("missing timestamp"))?;
let signature_header = headers.get("X-Signature")
.ok_or_else(|| actix_web::error::ErrorUnauthorized("missing signature"))?;
let key = credentials.get("hmac_secret")
.ok_or_else(|| actix_web::error::ErrorUnauthorized("server misconfiguration"))?;
let mut mac = HmacSha256::new_from_slice(key.as_bytes())
.map_err(|_| actix_web::error::ErrorUnauthorized("hmac init failed"))?;
// Construct the data to verify: method, path, timestamp, and body if present
let body = match req.get_payload().next().await {
Some(Ok(chunk)) => { mac.update(&chunk); chunk.to_vec() },
_ => vec![],
};
mac.update(method.as_str().as_bytes());
mac.update(path.as_bytes());
mac.update(timestamp.as_bytes());
let expected = mac.finalize();
let result = expected.verify_slice(signature_header.as_bytes());
if result.is_err() {
return Err(actix_web::error::ErrorUnauthorized("invalid signature"));
}
// Ensure the request is authenticated (e.g., check an auth token or session)
// In practice, you would validate an API key, JWT, or session here.
// For this example, we assume a header "X-Auth-Token" is required alongside HMAC.
let auth_token = headers.get("X-Auth-Token")
.ok_or_else(|| actix_web::error::ErrorUnauthorized("missing auth token"))?;
if auth_token != "expected_public_key_or_valid_session" {
return Err(actix_web::error::ErrorUnauthorized("unauthorized"));
}
next.call(req).await
}
async fn public_endpoint() -> impl Responder {
HttpResponse::Ok().body("Public info, no auth required")
}
async fn admin_endpoint() -> impl Responder {
HttpResponse::Ok().body("Admin data")
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let mut credentials = HashMap::new();
credentials.insert("hmac_secret".to_string(), "supersecretvalue123".to_string());
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(credentials.clone()))
.service(
web::resource("/public")
.route(web::get().to(public_endpoint))
)
.service(
web::resource("/admin")
.route(web::get().to(admin_endpoint))
.wrap_fn(|req, srv| {
verify_hmac(req, web::Data::new(credentials.clone()), srv)
})
)
})
.bind("127.0.0.1:8080")?
.run()
.await
}
In this example, /admin requires both a valid HMAC signature and an explicit authentication token, ensuring that missing authentication is not bypassed by a correct signature. The HMAC verification uses method, path, timestamp, and body to prevent replay and tampering. For broader protection, apply the same verify_hmac guard to all sensitive routes and keep public endpoints separate. middleBrick can detect whether routes inconsistently require authentication and will surface these gaps with prioritized findings and remediation steps.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |