Mass Assignment in Actix with Hmac Signatures
Mass Assignment in Actix with Hmac Signatures — how this specific combination creates or exposes the vulnerability
Mass assignment occurs when an API binds incoming JSON or form data directly to a data model, setting properties that were not intended to be user-controlled. In Actix web applications, this commonly happens when deserializing request payloads into structs using serde. If the struct contains fields such as is_admin, role, or user_id, an attacker can supply these keys in the request and escalate privileges or bypass authorization checks.
Combining mass assignment with Hmac Signatures introduces a nuanced risk. Hmac Signatures are often used to ensure request integrity and authenticity, for example by signing a subset of request parameters or the entire payload and verifying the signature server-side. However, if the application verifies the Hmac but still performs unchecked deserialization of all incoming fields, an attacker can manipulate allowed fields while the signature remains valid. The signature may cover only selected parameters (such as action and timestamp), while the server inadvertently trusts other parameters bound to the model. This mismatch between integrity protection and data binding creates a path where an attacker can inject or modify sensitive properties despite the presence of Hmac verification.
Consider a scenario where an endpoint accepts a JSON payload for updating user settings and uses an Hmac-SHA256 signature to guard against tampering. The client computes the signature over selected fields, but the server deserializes the full JSON into a struct that includes sensitive flags like is_premium or role. Because the deserialization is not restricted, the attacker can include "role": "admin" in the request. Even though the Hmac validates, the application applies the bound struct directly, granting unintended permissions. This pattern is common in forms or APIs where partial signing is used for replay protection but authorization logic relies on data from the same deserialized object.
Real-world attack patterns include privilege escalation via mass assignment when Hmac verification is narrowly scoped. For instance, an attacker might replay a legitimate request with modified fields, exploiting the gap between what is signed and what is bound. The presence of Hmac Signatures may create a false sense of security, leading developers to believe that integrity checks are sufficient to prevent tampering. In practice, without strict input filtering or explicit denylists/allowlists during deserialization, the combination remains vulnerable to OWASP API Top 10:2023 Broken Object Level Authorization (BOLA) and IDOR.
Hmac Signatures-Specific Remediation in Actix — concrete code fixes
To remediate mass assignment risks in Actix when Hmac Signatures are in use, you should enforce strict separation between integrity verification and data binding. Do not rely on the Hmac to implicitly protect fields; explicitly define which fields are user-controllable and which are server-controlled. Use dedicated DTOs (Data Transfer Objects) that contain only the fields necessary for the operation, and avoid binding directly to domain models.
Below are concrete code examples for Actix using Rust with the serde and hmac crates. The first example demonstrates the vulnerable pattern where an Hmac is verified but mass assignment is still possible. The second example shows a secure approach with a restricted DTO and selective field handling.
Vulnerable pattern: Hmac verified, but struct includes sensitive fields
use actix_web::{web, HttpResponse, Result};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
struct UserSettings {
user_id: u64,
display_name: String,
// This field should not be user-supplied
is_admin: bool,
}
async fn update_settings_form(
payload: web::Json,
// Assume signature verification happened earlier, e.g., via a custom guard
) -> Result {
// Risky: directly using payload to update domain model or database
// is_admin may have been set by the attacker
Ok(HttpResponse::Ok().finish())
}
Secure remediation: use a restricted DTO and explicit mapping
use actix_web::{web, HttpResponse, Result};
use serde::{Deserialize, Serialize};
use hmac::{Hmac, Mac};
use sha2::Sha256;
type HmacSha256 = Hmac;
#[derive(Deserialize)]
struct UpdateSettingsDto {
display_name: String,
// Only include fields the client is allowed to set
}
#[derive(Serialize)]
struct SettingsResponse {
user_id: u64,
display_name: String,
is_admin: bool,
}
async fn verify_hmac(
body: &str,
received_sig: &str,
key: &[u8],
) -> bool {
let mut mac = HmacSha256::new_from_slice(key).expect("HMAC can take key of any size");
mac.update(body.as_bytes());
let result = mac.verify_slice(received_sig.as_bytes());
result.is_ok()
}
async fn update_settings_secure(
web::Query(params): web::Query>,
web::Header(headers): web::Header<headers::Authorization<headers::authorization::Bearer>>,
body: String,
) -> Result {
// Example: signature covers selected parameters (e.g., display_name)
let signature = params.signature.clone(); // passed as separate query/form param
if !verify_hmac(¶ms.display_name, &signature, b"secret-key") {
return Ok(HttpResponse::Unauthorized().finish());
}
// Explicit mapping to domain model; sensitive fields are set server-side
let settings = SettingsResponse {
user_id: get_current_user_id_from_auth().unwrap_or_default(),
display_name: params.display_name,
is_admin: false, // determined by server logic, not user input
};
// Proceed with safe update
Ok(HttpResponse::Ok().json(settings))
}
In the secure pattern, the DTO UpdateSettingsDto contains only user-controllable fields. The Hmac verification operates on a canonical representation (e.g., a subset of parameters or a normalized string), and the server sets sensitive fields such as is_admin based on authorization logic rather than user input. This ensures that even if mass assignment were possible, the payload cannot elevate privileges or leak sensitive data through form binding.
Additionally, prefer using #[serde(deny_unknown_fields)] on DTOs to reject unexpected keys, and validate and normalize inputs before any further processing. Combine this with framework-level authorization checks to enforce least privilege, ensuring that Hmac Signatures protect integrity while explicit handling governs authorization.
Related CWEs: propertyAuthorization
| CWE ID | Name | Severity |
|---|---|---|
| CWE-915 | Mass Assignment | HIGH |