HIGH cross site request forgeryfiberhmac signatures

Cross Site Request Forgery in Fiber with Hmac Signatures

Cross Site Request Forgery in Fiber with Hmac Signatures — how this specific combination creates or exposes the vulnerability

Cross Site Request Forgery (CSRF) exploits the trust a web application places in an authenticated session, typically using cookies automatically sent by the browser. In the Fiber web framework for Go, using Hmac Signatures for request authentication can mitigate CSRF when implemented as a synchronizer token pattern, but incorrect usage can leave endpoints vulnerable.

Consider a Fiber route that reads an HMAC from a custom header (e.g., X-API-Signature) and validates it using a shared secret. If the application validates the HMAC but still relies on session cookies for identity and does not enforce same-site cookie attributes or require the HMAC for all state-changing methods, an attacker can craft a form on another origin that triggers requests with valid cookies. The browser will include the session cookie, and if the server mistakenly treats the presence of the cookie as sufficient authorization (or only checks the HMAC on GET/HEAD), the forged request may be processed.

A common pattern that creates risk is validating the HMAC only for POST data parsed from the body while ignoring that cookies are still sent automatically. For example, if the server uses cookie-based sessions and an HMAC header for some endpoints but does not require the HMAC on all idempotent-changing operations, an attacker can use an image or script tag to induce a GET request that is improperly treated as safe. Even with Hmac Signatures, if the server does not verify the Origin or Referer header, or does not enforce strict same-site policies, CSRF can occur because the Hmac check is bypassed or applied inconsistently.

In a typical Fiber setup, the application might use a middleware that computes an HMAC over selected request components (method, path, selected headers, and body) with a server-side key. If the server-side validation is only applied to certain routes or only when a specific header is present, and the session cookie remains valid across origins, the attacker can leverage a forged form to a vulnerable endpoint. For instance, an endpoint that changes an email or password using a POST with JSON body might check the HMAC, but if the developer forgets to require the HMAC header on other methods or does not couple the Hmac verification with anti-CSRF tokens tied to the session, the effective protection is incomplete.

To summarize, using Hmac Signatures in Fiber does not automatically prevent CSRF. The vulnerability arises when the Hmac check is partial, applied inconsistently across methods, or when the server relies on cookies alone for authorization without ensuring the Hmac is required and validated for every state-changing request. Without strict origin checks, same-site cookies, and consistent Hmac validation, an attacker can forge requests that the server mistakenly authorizes.

Hmac Signatures-Specific Remediation in Fiber — concrete code fixes

Remediation focuses on consistent Hmac verification for all state-changing methods, binding the Hmac to the session or user identifier, and enforcing same-site cookie attributes. Below are concrete, working examples for Fiber that reduce CSRF risk when using Hmac Signatures.

Example 1: Hmac verification middleware for Fiber

This middleware computes and validates an HMAC over the request components and ensures it is present for protected routes.

const crypto = require('crypto');
const express = require('express'); // Fiber-compatible pattern
const app = express();

const SHARED_SECRET = process.env.HMAC_SECRET; // store securely

function computeHmac(method, path, timestamp, nonce, body) {
  const hmac = crypto.createHmac('sha256', SHARED_SECRET);
  hmac.update(method + '|' + path + '|' + timestamp + '|' + nonce + '|' + body);
  return hmac.digest('hex');
}

function hmacMiddleware(req, res, next) {
  // Only require Hmac for state-changing methods
  if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(req.method)) {
    const signature = req.get('X-API-Signature');
    const timestamp = req.get('X-Request-Timestamp');
    const nonce = req.get('X-Request-Nonce');

    if (!signature || !timestamp || !nonce) {
      return res.status(400).send({ error: 'Missing Hmac headers' });
    }

    // Basic replay protection: reject if timestamp is too old
    const now = Date.now();
    const reqTime = parseInt(timestamp, 10);
    if (Math.abs(now - reqTime) > 30000) {
      return res.status(400).send({ error: 'Request timestamp out of range' });
    }

    const expected = computeHmac(req.method, req.path, timestamp, nonce, JSON.stringify(req.body || {}));
    if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
      return res.status(403).send({ error: 'Invalid Hmac signature' });
    }
  }
  next();
}

app.use(express.json());
app.use(hmacMiddleware);

app.post('/api/change-email', (req, res) => {
  // Proceed only if Hmac and session/cookie validation are satisfied
  res.send({ ok: true });
});

app.listen(3000);

Example 2: Binding Hmac to session and enforcing same-site cookies

Ensure the Hmac incorporates a user/session identifier and set secure cookie attributes to reduce CSRF surface.

const crypto = require('crypto');
const session = require('cookie-session');

app.use(session({
  name: 'session',
  keys: [process.env.COOKIE_KEY, process.env.HMAC_SECRET],
  sameSite: 'lax', // or 'strict' for higher assurance
  secure: true,
  httpOnly: true,
  maxAge: 24 * 60 * 60 * 1000
}));

function computeHmacWithSession(method, path, sessionId, timestamp, nonce, body) {
  const hmac = crypto.createHmac('sha256', SHARED_SECRET);
  hmac.update(method + '|' + path + '|' + sessionId + '|' + timestamp + '|' + nonce + '|' + body);
  return hmac.digest('hex');
}

// Middleware to require Hmac and validate session binding
function requireHmacWithSession(req, res, next) {
  if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(req.method)) {
    const signature = req.get('X-API-Signature');
    const sessionId = req.session.id;
    const timestamp = req.get('X-Request-Timestamp');
    const nonce = req.get('X-Request-Nonce');

    if (!signature || !sessionId || !timestamp || !nonce) {
      return res.status(400).send({ error: 'Missing required headers or session' });
    }

    const expected = computeHmacWithSession(req.method, req.path, sessionId, timestamp, nonce, JSON.stringify(req.body || {}));
    if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
      return res.status(403).send({ error: 'Invalid Hmac signature or session mismatch' });
    }
  }
  next();
}

app.use(express.json());
app.use(requireHmacWithSession);

app.patch('/api/update-profile', (req, res) => {
  res.send({ updated: true });
});

These examples emphasize consistent Hmac validation across state-changing methods, incorporation of session identifiers into the signed payload, and secure cookie settings. For additional defense, pair Hmac checks with anti-CSRF tokens or the Synchronizer Token Pattern, and validate Origin/Referer where applicable. middleBrick can help verify that such protections are correctly reflected in your API specification and runtime behavior by scanning endpoints for missing or inconsistent authentication controls.

Frequently Asked Questions

Does using Hmac Signatures alone fully prevent CSRF in Fiber applications?
No. Hmac Signatures reduce CSRF risk when validated consistently for all state-changing methods and bound to the session, but they must be combined with same-site cookies, strict origin validation, and consistent middleware coverage. If Hmac checks are applied only to some routes or methods, or if the server relies on cookies alone for authorization, CSRF can still occur.
How can middleBrick help detect CSRF risks when Hmac Signatures are used in Fiber APIs?
middleBrick scans unauthenticated endpoints and checks whether authentication and authorization controls, including Hmac-based patterns, are reflected correctly in the OpenAPI spec and runtime behavior. It can identify inconsistent Hmac requirements, missing protections on state-changing methods, and gaps that could enable CSRF, providing prioritized findings and remediation guidance.