Executive Summary
CVE-2026-82454 affects the Omnivore API (packages/api) prior to the fix in commit abf53d6, and carries a critical CVSS score of 9.1. The flaw is an authentication bypass in Omnivore's Apple Sign-In token verification, caused by a classic JWT algorithm confusion vulnerability.
CVSS Score: 9.1 (Critical) — CVSS 4.0: 9.3
Omnivore's decodeAppleToken function extracted the alg field directly from the attacker-supplied JWT header and passed it as the sole allowed algorithm to jwt.verify(). Because Omnivore relies on jsonwebtoken v8, which does not validate that a key is actually appropriate for the algorithm being used, an attacker can set alg=HS256 in a forged token and sign it using Apple's publicly available RSA public key as the HMAC secret. Since that key is public by design (it exists to verify RS256 signatures), the server incorrectly validates the forged HMAC signature and accepts the token as genuine — letting an attacker impersonate any Apple-linked account. The fix ships in commit abf53d6 (pull request #4652), included in Omnivore android-0.227.0 and later.
Vulnerability Overview
| Attribute | Value |
|---|---|
| CVE ID | CVE-2026-82454 |
| CVSS Score | 9.1 (Critical) — CVSS 4.0: 9.3 |
| Type | JWT Algorithm Confusion → Authentication Bypass (CWE-347) |
| Attack Vector | Network |
| Privileges Required | None |
| User Interaction | None |
| Assigner | VulnCheck |
| Vulnerable Function | decodeAppleToken |
Affected Versions
| Product | Affected Versions | Fixed Version |
|---|---|---|
| Omnivore API | Before commit abf53d6 | Commit abf53d6 (PR #4652) — Omnivore android-0.227.0 and later |
Technical Details
Apple Sign-In issues identity tokens as RS256-signed JWTs, verified using Apple's published RSA public key. A server verifying these tokens correctly should hardcode RS256 as the only accepted algorithm and use the RSA public key strictly as an RSA key.
Omnivore's decodeAppleToken instead read the algorithm to use for verification from the incoming token's own header rather than pinning it server-side, and passed that attacker-controlled value straight into jwt.verify(). This is exploitable because jsonwebtoken v8 does not enforce that the algorithm family matches the key type supplied.
An attacker can therefore:
- Craft a JWT header specifying
alg: HS256instead of the expectedRS256. - Sign the token using Apple's public RSA key — normally used only to verify signatures — as if it were a shared HMAC secret.
- Submit the forged token to Omnivore's Apple sign-in endpoint.
Because the server trusts the attacker-declared alg and Apple's public key is, by definition, public, the HMAC signature validates successfully, and Omnivore accepts the forged token as a legitimate Apple-issued identity assertion for any account the attacker chooses to impersonate.
Attack Vector
1. Attacker obtains Apple's publicly published RSA public key (freely available)
2. Attacker crafts a JWT claiming to be an Apple identity token for a target user,
setting the header algorithm to alg=HS256
3. Attacker signs the token using Apple's RSA public key as the HMAC secret
4. Attacker submits the forged token to Omnivore's Apple sign-in flow
5. decodeAppleToken trusts the attacker-supplied alg and validates via HMAC
6. Server accepts the forged token, authenticating the attacker as the target userImpact of Successful Exploitation
| Impact | Description |
|---|---|
| Account Takeover | Impersonate any user who signed up or linked their account via Apple Sign-In |
| No Authentication Barrier | Exploitation requires no valid Apple credentials, only a forged token |
| Silent Exploitation | Forged tokens are indistinguishable from legitimate ones at the application layer |
| Data Exposure | Full access to the impersonated account's saved content and settings |
Immediate Remediation
Step 1: Update Omnivore
git fetch origin
git log --oneline | grep abf53d6
# Update to android-0.227.0 or later, or apply commit abf53d6 directlyStep 2: Pin the Verification Algorithm Server-Side
If running a fork or delayed deployment, patch decodeAppleToken (or equivalent) to hardcode the expected algorithm rather than reading it from the token:
// Vulnerable pattern — do not use
const alg = decodedHeader.alg;
jwt.verify(token, applePublicKey, { algorithms: [alg] });
// Correct pattern
jwt.verify(token, applePublicKey, { algorithms: ["RS256"] });Step 3: Upgrade the JWT Library
Consider upgrading past jsonwebtoken v8 to a version that enforces key/algorithm-type matching as an additional layer of defense, independent of application-level algorithm pinning.
Step 4: Audit for Prior Exploitation
# Review authentication logs for Apple sign-in events with unusual patterns,
# such as repeated failed/forged token attempts against specific accounts
grep -i "apple" /var/log/omnivore/auth*.logDetection Indicators
| Indicator | Description |
|---|---|
Apple sign-in JWTs with alg: HS256 in the header | Direct evidence of a forged token attempt |
| Successful Apple sign-in events with no corresponding Apple-side session | Sign of a bypassed verification |
| Unexpected account access following an Apple sign-in event | Possible successful account takeover |
Post-Remediation Steps
- Confirm the deployment includes commit
abf53d6or android-0.227.0+. - Force re-authentication for all accounts linked via Apple Sign-In.
- Review account activity for signs of prior unauthorized access.
- Audit any other JWT verification paths in the codebase for the same attacker-controlled-
algpattern. - Add algorithm pinning as a standing code-review requirement for all JWT verification logic.