HIGH formula injectionaspnethmac signatures

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.

Frequently Asked Questions

Does HMAC protect against Formula Injection if the parameters are used in arithmetic?
No. HMAC ensures authenticity and integrity of parameters but does not prevent unsafe evaluation. If signed parameters are fed into dynamic evaluators or poorly validated arithmetic, Formula Injection can still occur. Validate and type-check inputs before use.
Can an attacker bypass HMAC by injecting formula-like strings into numeric fields?
Yes, if the server reinterprets signed numeric fields using expression parsers or loose conversions. Use strict schema validation, avoid eval-like parsing, and treat signed values as opaque inputs rather than executable formulas.