CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-22818
8.20.02%

Hono-rary Mention: Authentication Bypass via JWT Algorithm Confusion

Alon Barad
Alon Barad
Software Engineer

Feb 20, 2026·6 min read·6 visits

PoC Available

Executive Summary (TL;DR)

Hono < 4.11.4 trusts the JWT header 'alg' field when the JWK Set doesn't explicitly define one. Attackers can sign malicious tokens using the victim's public key as an HMAC secret (HS256), forging valid sessions.

A critical vulnerability in the Hono web framework's JWK middleware allows attackers to perform a classic JWT Algorithm Confusion attack. By manipulating the JWT header, an attacker can trick the server into verifying an asymmetric signature (RS256) as a symmetric HMAC (HS256) using the server's public key as the shared secret. This results in full authentication bypass and privilege escalation.

The Hook: Trusting the Untrustworthy

In the world of web standards, flexibility is often the enemy of security. Hono, a blisteringly fast web framework designed for the Edge (Cloudflare Workers, Deno, Bun), usually gets things right. But in the implementation of its JSON Web Key (JWK) middleware, it fell victim to a vulnerability class that has been haunting JWT libraries since 2015: Algorithm Confusion.

Here is the setup: You want to verify JWTs signed by an OIDC provider (like Auth0 or Google). You configure Hono to fetch the provider's public keys (JWKS). Everything looks secure because you are validating cryptographic signatures. However, Hono's middleware made a fatal assumption: it assumed that if the key didn't tell you how to use it, the token would.

This is the digital equivalent of a bank teller verifying a check not by looking at the bank's security features, but by asking the robber, "Does this look real to you?" If the robber says yes (and specifies the verification method), the teller proceeds. CVE-2026-22818 is exactly this: a mechanism where the attacker dictates the rules of engagement, turning the server's own public keys against it.

The Flaw: A Tale of Two Algorithms

To understand this exploit, you have to understand the difference between Asymmetric (RSA/EC) and Symmetric (HMAC) signatures. In a normal RSA flow (RS256), the server uses a Public Key to verify a signature created by a Private Key. In an HMAC flow (HS256), both parties share a single Secret to sign and verify.

The vulnerability exists in src/middleware/jwk/index.ts. When Hono fetches a JWK from a remote endpoint, that key object might look like this: {"kty": "RSA", "kid": "123", "n": "...", "e": "AQAB"}. Notice something missing? The alg field (e.g., "alg": "RS256") is optional in RFC 7517. If the OIDC provider omits it, Hono has to guess which algorithm to use.

Before version 4.11.4, Hono's logic was roughly: "If the Key doesn't specify an algorithm, use the one listed in the JWT header." This is catastrophic. An attacker can change the JWT header to {"alg": "HS256"}. The middleware sees the header, looks up the key, finds no specific algorithm bound to the key, and agrees to verify the token using HS256. The "secret" used for this HMAC verification becomes the Public Key string itself. Since the Public Key is, by definition, public, the attacker has everything they need to forge a signature.

The Code: The Smoking Gun

Let's dissect the vulnerable code in src/utils/jwt/jwt.ts. The logic flow was a textbook example of fallback insecurity. The verify function prioritized the header's claim over strict configuration.

The Vulnerable Logic:

// Pseudocode representation of the flaw
const verifyWithJwks = async (token, jwks) => {
  const header = decodeHeader(token);
  const key = findKey(jwks, header.kid);
  
  // CRITICAL FAIL: Fallback to untrusted header
  const algorithm = key.alg || header.alg;
  
  return await verify(token, key, algorithm);
};

Because key.alg is often undefined in wild JWKS implementations, the code defaults to header.alg. If the header says HS256, the verify function uses the PEM representation of key as the HMAC secret.

The Fix (Commit 190f6e2): The patch introduces a breaking change that forces the developer to explicitly allow-list algorithms. It also strictly validates that the header matches the allowed list.

// The patched approach
if (!allowedAlgorithms.includes(header.alg)) {
    throw new Error('Invalid algorithm');
}
 
// Explicitly reject symmetric algs in JWK context
if (header.alg.startsWith('HS')) {
    throw new Error('Symmetric algorithm not allowed');
}

By enforcing an allowlist and banning HS* algorithms within the JWK context, Hono ensures that a public key is never reinterpreted as a shared secret.

The Exploit: Forging the Admin Token

Re-exploiting this requires zero access to the internal network; you just need to know the target is using Hono and where they get their keys (usually a public .well-known/jwks.json endpoint).

Step 1: Reconnaissance The attacker grabs the JWKS from the target's provider (e.g., https://example.com/.well-known/jwks.json). They extract the RSA public key components (n and e).

Step 2: Key Conversion The attacker converts this JWK into a PEM string. This string is what the server uses as the "key" object. In Node.js/WebCrypto, when you pass a public key object to an HMAC verify function, it simply serializes the key structure.

Step 3: The Forgery The attacker constructs a JWT:

  • Header: {"alg": "HS256", "typ": "JWT", "kid": "<valid_kid_from_jwks>"}
  • Payload: {"sub": "attacker", "role": "admin", "iss": "https://trusted.provider"}

Now, the magic trick: The attacker signs this token using HS256. For the secret key, they use the Public Key PEM they extracted in Step 1.

Step 4: Delivery The attacker sends Authorization: Bearer <forged_token>. Hono reads the header (HS256), fetches the correct public key (via kid), and attempts to verify the signature as an HMAC using that public key. Since the attacker signed it with the exact same data, the math checks out. The server grants admin access.

The Impact: Why Panic?

This vulnerability scores an 8.2 (High) for a reason. While it requires a specific configuration (JWKs without explicit alg fields), that configuration is extremely common. Many OIDC providers do not include the alg field in their JWKS to maintain flexibility during key rotation.

The impact is a complete bypass of authentication. If your application relies on the JWT for authorization (e.g., checking scope or role claims), the attacker can grant themselves any permission they desire. They become the superuser.

Furthermore, because this is an implementation flaw in the verification logic, it affects any Hono-based application exposed to the internet, regardless of whether it's running on AWS Lambda, Cloudflare Workers, or a standard Node.js container. It is a logic bug, not a memory corruption bug, making it reliable and stable to exploit.

The Fix: Stopping the Bleeding

The remediation is straightforward but requires code changes due to the breaking nature of the fix in version 4.11.4.

1. Update Hono Upgrade your dependency immediately: npm install hono@latest (Ensure version is >= 4.11.4).

2. Update Middleware Config The jwk() middleware now requires you to specify which algorithms you accept. You can no longer rely on auto-detection.

import { jwk } from 'hono/jwk'
 
app.use('/protected/*', jwk({
  jwks_uri: 'https://example.auth0.com/.well-known/jwks.json',
  alg: 'RS256' // YOU MUST SET THIS NOW
}))

3. Audit Logs Check your access logs for JWTs using HS256 (HMAC) on routes that should be using RS256 (RSA). If you see HS256 headers coming into your OIDC-protected endpoints, you have likely been probed or compromised.

Official Patches

HonoOfficial patch enforcing algorithm allowlists

Fix Analysis (1)

Technical Appendix

CVSS Score
8.2/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
EPSS Probability
0.02%
Top 96% most exploited

Affected Systems

Hono Web Framework (Node.js, Deno, Bun, Cloudflare Workers)

Affected Versions Detail

Product
Affected Versions
Fixed Version
hono
honojs
< 4.11.44.11.4
AttributeDetail
CWE IDCWE-347
Attack VectorNetwork
CVSS Score8.2 (High)
EPSS Score0.00017
VulnerabilityJWT Algorithm Confusion
Exploit StatusPoC Available

MITRE ATT&CK Mapping

T1557Adversary-in-the-Middle
Credential Access
T1190Exploit Public-Facing Application
Initial Access
CWE-347
Improper Verification of Cryptographic Signature

Improper Verification of Cryptographic Signature

Known Exploits & Detection

GitHubProof of Concept test case included in the remediation commit

Vulnerability Timeline

Vulnerability Disclosed & CVE Assigned
2026-01-13
Patch v4.11.4 Released
2026-01-13
PoC Test Case Published
2026-01-13

References & Sources

  • [1]GitHub Advisory
  • [2]NVD Entry

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.