The Wrong Audience — JavaScript Bug Hunt

Inspired by the cross-service token confusion behind several real IdP advisories: a token minted for the analytics API is happily accepted by the payments…

  • Language: JavaScript
  • Layer: Backend
  • Difficulty: Medium
  • Concepts: Security, JWT
  • Modelled on: OAuth deployments
  • Visible tests: a fully matching token passes; the wrong audience is rejected; expired tokens are rejected
  • Reward: 50 XP for a complete fix

Briefing

Inspired by the cross-service token confusion behind several real IdP advisories: a token minted for the analytics API is happily accepted by the payments API, because nobody checks the aud claim. Same issuer, wrong audience, full access.

claims.js validates a decoded token's claims.

Bug report

BUG-AUD · Priority: Critical · Reported by: security review

validateClaims(claims, expected, nowSeconds):

  • claims.iss must equal expected.issuer
  • claims.aud must equal expected.audience <- the missing check
  • claims.exp must be strictly in the future

Observed: any token from our issuer opens every service.

Logs

[payments] accepted token aud="analytics-api" (we are payments-api)

The code as shipped

src/auth/claims.js (editable)

// Validates decoded token claims.
exports.validateClaims = function (claims, expected, nowSeconds) {
  if (claims.iss !== expected.issuer) return false;
  return true;
};

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More JavaScript bug hunts.