HIGH prototype pollutionfiberhmac signatures

Prototype Pollution in Fiber with Hmac Signatures

Prototype Pollution in Fiber with Hmac Signatures — how this specific combination creates or exposes the vulnerability

Prototype pollution in Fiber applications that use Hmac signatures occurs when user-controlled input reaches object merge operations before signature validation, or when the signature is computed over a mutable object graph. In JavaScript, objects inherit properties from their prototype; if an attacker can inject keys such as __proto__, constructor.prototype, or other special keys into a merged object, they can modify behavior for all instances or cause unexpected logic in downstream checks.

Consider a Fiber route that parses JSON payloads and merges them with a server-side defaults object before validating an Hmac signature. If the client sends:

{ "amount": 100, "__proto__": { "isAdmin": true } }

and the server performs a shallow merge before computing the Hmac over the merged object, the pollution may not be caught by the signature because the signature was computed after the merge or over a representation that still contains the polluted keys. In an unsafe consumption flow, the merged object is then used to instantiate classes or drive routing logic, enabling behavior manipulation such as privilege escalation or unintended method execution.

When Hmac signatures are generated from query-string parameters, headers, or JSON bodies without canonicalization, an attacker can exploit ordering differences, nested objects, or prototype keys to create signature collisions or bypass intended constraints. For example, two semantically different payloads that resolve to the same canonical string only after normalization would produce the same Hmac, allowing injection to go undetected if the server does not enforce strict schema validation prior to signing. The vulnerability is not in Hmac itself but in how the data fed into the signing process is structured and validated.

Additionally, if the application exposes an unauthenticated endpoint that returns sensitive object structures and relies on prototype checks for access control, polluted prototypes can bypass those checks at runtime. This highlights the importance of validating and sanitizing input before any cryptographic verification and object construction in Fiber routes.

Hmac Signatures-Specific Remediation in Fiber — concrete code fixes

To remediate prototype pollution when using Hmac signatures in Fiber, ensure input is deeply validated and canonicalized before signing, and avoid merging user input into shared prototypes. Use strict schema validation and compute Hmac over a normalized, deterministic representation of the data.

Example 1: Validate and canonicalize JSON before signing with Hmac in Fiber.

const crypto = require('crypto');
const { app, json } = require('@ginier/fiber');

function canonicalStringify(obj) {
  return JSON.stringify(obj, Object.keys(obj).sort());
}

app.post('/payment', json(), (c) => {
  const body = c.body;
  // Strict validation: only allow expected keys
  if (typeof body.amount !== 'number' || typeof body.currency !== 'string') {
    c.status(400).send({ error: 'invalid payload' });
    return;
  }
  const canonical = canonicalStringify(body);
  const hmac = crypto.createHmac('sha256', process.env.HMAC_SECRET)
                     .update(canonical)
                     .digest('hex');
  const received = c.get('X-Signature');
  if (!crypto.timingSafeEqual(Buffer.from(hmac), Buffer.from(received))) {
    c.status(401).send({ error: 'invalid signature' });
    return;
  }
  c.send({ ok: true });
});

This approach removes prototype keys by validating types and allowed fields, then canonicalizing with sorted keys to ensure consistent Hmac input. It prevents __proto__ injection because such keys are not part of the validated schema.

Example 2: Use a schema-aware library and verify before merging defaults, then sign the validated subset.

const crypto = require('crypto');
const { app, json } = require('@ginier/fiber');

function computeHmac(secret, data) {
  const canonical = JSON.stringify(data, Object.keys(data).sort());
  return crypto.createHmac('sha256', secret).update(canonical).digest('hex');
}

app.post('/profile', json(), (c) => {
  const raw = c.body;
  // Explicitly pick allowed fields
  const safe = {
    username: typeof raw.username === 'string' ? raw.username : '',
    theme: raw.theme === 'dark' || raw.theme === 'light' ? raw.theme : 'light'
  };
  const expected = computeHmac(process.env.HMAC_SECRET, safe);
  const actual = c.get('X-Profile-Sig');
  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(actual))) {
    c.status(403).send({ error: 'forbidden' });
    return;
  }
  // Merge after validation and signing
  const profile = { ...safe, createdAt: new Date() };
  c.send(profile);
});

By validating first, you eliminate prototype keys and ensure the Hmac covers only the intended data. Combine this with runtime checks that do not rely on prototype properties (e.g., use Object.hasOwn or Map for access control) to reduce risk. The Fiber ecosystem does not need to change; the fix is in how data is prepared and verified before cryptographic operations.

Frequently Asked Questions

Does using JSON.parse with reviver prevent prototype pollution in Fiber Hmac flows?
A reviver can delete dangerous keys, but it does not guarantee canonical ordering for Hmac. Prefer strict schema validation and sorted canonicalization before signing.
Can an attacker bypass Hmac signatures via prototype pollution if the signature is computed after sanitization?
If sanitization occurs before signing and only expected, validated fields are included, prototype pollution cannot alter the signed data. Ensure merged defaults are not shared with user-controlled objects.