Formula Injection in Aspnet with Hmac Signatures
Formula Injection in Aspnet with Hmac Signatures — how this specific combination creates or exposes the vulnerability
Formula Injection in ASP.NET occurs when an attacker can influence a formula, expression, or logic evaluated server-side, often via user-controlled input. When HMAC signatures are used to bind requests to shared secrets, a subtle misconfiguration can turn the signature into part of the evaluatable formula, creating a Formula Injection vector.
Consider an ASP.NET endpoint that builds a signing string by concatenating user-controlled fields (e.g., price, currency, orderId) and then computes an HMAC to verify integrity. If the server reuses these fields directly in business logic—such as computing totals or applying discounts—without strict validation, an attacker can inject crafted values that alter the formula outcome. For example, a numeric price field may be multiplied or summed in server-side calculations; if an attacker provides a value like 10*100 or a formula-like string that is later interpreted by a loosely parsed evaluator, the server may execute unintended arithmetic.
In the HMAC verification flow, the signature ensures the parameters have not been tampered with, but it does not guarantee the parameters are semantically safe for evaluation. If the ASP.NET application deserializes or parses the signed parameters using dynamic evaluation (e.g., DataTable.Compute, System.Linq.Dynamic, or custom parsers that interpret expressions), an attacker can embed formulas such as 1;DROP TABLE Orders; or arithmetic like 1000*1000 to cause overflow, resource exhaustion, or logic bypass. Because the signature validates authenticity but not safety, the combination of Formula Injection and HMAC Signatures can lead to unauthorized price changes, privilege escalation via crafted discount rules, or data corruption.
Real-world patterns include using signed query strings in payment flows where amount and productId are signed and then passed to a calculation routine. If the routine does not strictly type-check and sanitize inputs before arithmetic, signed parameters can become injection vectors. Similarly, in inventory or shipping cost APIs, signed numeric fields that are later evaluated in expressions can be abused to manipulate totals or trigger incorrect branching logic.
To detect this class of issues, scans examine whether signed parameters are used in any server-side evaluatable context, whether input validation occurs before HMAC verification, and whether the framework’s model binding introduces implicit conversions that could interpret attacker-supplied strings as code or formulas. The presence of HMAC does not mitigate unsafe evaluation; it only authenticates the payload, making the risk subtle and easily missed.
Hmac Signatures-Specific Remediation in Aspnet — concrete code fixes
Remediation centers on strict input validation, avoiding dynamic evaluation, and ensuring HMAC verification is applied after canonicalization. Never compute or interpret signed parameters using eval-like mechanisms. Instead, use strongly typed models, explicit parsing, and constant-time comparison for signatures.
Example 1: Safe parameter parsing with HMAC validation in ASP.NET Core.
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNetCore.Mvc;
public class PaymentRequest {
public decimal Amount { get; set; }
public string Currency { get; set; }
public string OrderId { get; set; }
}
[ApiController]
[Route("api/payment")]
public class PaymentController : ControllerBase {
private const string Secret = "your-256-bit-secret";
[HttpPost("process")]
public IActionResult Process([FromBody] PaymentRequest req) {
// Validate model state first
if (!ModelState.IsValid) {
return BadRequest("Invalid input");
}
// Recompute HMAC from received data (except signature) and compare
var computed = ComputeHmac(req.Amount, req.Currency, req.OrderId);
if (!VerifyHmac(computed, req.Signature)) {
return Unauthorized("Invalid signature");
}
// Safe, strongly-typed usage; no dynamic evaluation
decimal total = req.Amount; // direct use, no parsing
// ... business logic
return Ok(new { Total = total });
}
private string ComputeHmac(decimal amount, string currency, string orderId) {
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(Secret));
var payload = $"{amount}|{currency}|{orderId}";
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));
return Convert.ToBase64String(hash);
}
private bool VerifyHmac(string computed, string provided) {
// Constant-time comparison to avoid timing attacks
return CryptographicOperations.FixedTimeEquals(
Convert.FromBase64String(computed),
Convert.FromBase64String(provided)
);
}
}
Example 2: Canonicalization before signing in query strings to prevent injection via parameter ordering or encoding.
using System.Security.Cryptography;
using System.Text;
using System.Web;
public static class HmacUtils {
public static string BuildStringToSign(HttpRequest request) {
// Use a canonical order and strict encoding; exclude signature
var amount = HttpUtility.UrlEncode(request.Query["amount"]);
var currency = HttpUtility.UrlEncode(request.Query["currency"]);
var orderId = HttpUtility.UrlEncode(request.Query["orderId"]);
return $"amount={amount}¤cy={currency}&orderId={orderId}";
}
public static string ComputeQueryHmac(string baseString, string secret) {
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(baseString));
return Convert.ToBase64String(hash);
}
}
// In controller:
var baseString = HmacUtils.BuildStringToSign(Request);
var expected = HmacUtils.ComputeQueryHmac(baseString, "your-256-bit-secret");
var actual = Request.Query["signature"];
if (!actual.Equals(expected, StringComparison.Ordinal)) {
// reject
}
Key practices: validate and type-cast inputs before using them in arithmetic, avoid DataTable.Compute or dynamic LINQ on signed values, use fixed-time comparison for HMAC verification, and ensure canonical serialization (e.g., ordered key-value pairs) to prevent bypass via encoding tricks. These measures prevent Formula Injection while preserving the integrity guarantees of Hmac Signatures.