Skip to content

Conversation

@renovate
Copy link
Contributor

@renovate renovate bot commented Sep 14, 2025

This PR contains the following updates:

Package Change Age Confidence
hono (source) 4.7.10 -> 4.10.3 age confidence

GitHub Vulnerability Alerts

CVE-2025-59139

Summary

A flaw in the bodyLimit middleware could allow bypassing the configured request body size limit when conflicting HTTP headers were present.

Details

The middleware previously prioritized the Content-Length header even when a Transfer-Encoding: chunked header was also included. According to the HTTP specification, Content-Length must be ignored in such cases. This discrepancy could allow oversized request bodies to bypass the configured limit.

Most standards-compliant runtimes and reverse proxies may reject such malformed requests with 400 Bad Request, so the practical impact depends on the runtime and deployment environment.

Impact

If body size limits are used as a safeguard against large or malicious requests, this flaw could allow attackers to send oversized request bodies. The primary risk is denial of service (DoS) due to excessive memory or CPU consumption when handling very large requests.

Resolution

The implementation has been updated to align with the HTTP specification, ensuring that Transfer-Encoding takes precedence over Content-Length. The issue is fixed in Hono v4.9.7, and all users should upgrade immediately.

CVE-2025-62610

Improper Authorization in Hono (JWT Audience Validation)

Hono’s JWT authentication middleware did not validate the aud (Audience) claim by default. As a result, applications using the middleware without an explicit audience check could accept tokens intended for other audiences, leading to potential cross-service access (token mix-up).

The issue is addressed by adding a new verification.aud configuration option to allow RFC 7519–compliant audience validation. This change is classified as a security hardening improvement, but the lack of validation can still be considered a vulnerability in deployments that rely on default JWT verification.

Recommended secure configuration

You can enable RFC 7519–compliant audience validation using the new verification.aud option:

import { Hono } from 'hono'
import { jwt } from 'hono/jwt'

const app = new Hono()

app.use(
  '/api/*',
  jwt({
    secret: 'my-secret',
    verification: {
      // Require this API to only accept tokens with aud = 'service-a'
      aud: 'service-a',
    },
  })
)

Below is the original description by the reporter. For security reasons, it does not include PoC reproduction steps, as the vulnerability can be clearly understood from the technical description.


The original description by the reporter

Summary

Hono’s JWT Auth Middleware does not provide a built-in aud (Audience) verification option, which can cause confused-deputy / token-mix-up issues: an API may accept a valid token that was issued for a different audience (e.g., another service) when multiple services share the same issuer/keys. This can lead to unintended cross-service access. Hono’s docs list verification options for iss/nbf/iat/exp only, with no aud support; RFC 7519 requires that when an aud claim is present, tokens MUST be rejected unless the processing party identifies itself in that claim.

Note: This problem likely exists in the JWK/JWKS-based middleware as well (e.g., jwk / verifyWithJwks)

Details

  • The middleware’s verifyOptions enumerate only iss, nbf, iat, and exp; there is no aud option. The same omission appears in the JWT Helper’s “Payload Validation” list. Developers relying on the middleware for complete standards-aligned validation therefore won’t check audience by default.
  • Standards requirement: RFC 7519 §4.1.3 states that each principal intended to process the JWT MUST identify itself with a value in the aud claim; if it does not, the JWT MUST be rejected (when aud is present). Lack of a first-class aud check increases the risk that tokens issued for Service B are accepted by Service A.
  • Real-world effect: In deployments with a single IdP/JWKS and shared keys across multiple services, a token minted for one audience can be mistakenly accepted by another audience unless developers implement a custom audience check.
    • For example, with Google Identity (OIDC), iss is always https://accounts.google.com (shared across apps), but aud differs per application because it is that app’s OAuth client ID; therefore, an attacker can host a separate service that supports “Sign in with Google,” obtain a valid ID token (JWT) for the victim user, and—if your API does not verify aud—use that token to access your API with the victim’s privileges.

Impact

Type: Authentication/authorization weakness via token mix-up (confused-deputy).

Who is impacted: Any Hono user who:

  • shares an issuer/keys across multiple services (common with a single IdP/JWKS)
  • distinguishes tokens by intended recipient using aud.

What can happen:

  • Cross-service access: A token for Service B may be accepted by Service A.
  • Boundary erosion: ID tokens and access tokens, or separate API audiences, can be inadvertently intermixed.
    • This may causes unauthorized invocation of sensitive endpoints.

Recommended remediation:

  1. Add verifyOptions.aud (string | string[] | RegExp) to the middleware and enforce RFC 7519 semantics: In verify method, if aud is present and does not match with specified audiences, reject.
  2. Ensure equivalent aud handling exists in the JWK/JWKS flow (jwk middleware / verifyWithJwks) so users of external IdPs can enforce audience consistently.

GHSA-q7jf-gf43-6x6p

Summary

A flaw in the CORS middleware allowed request Vary headers to be reflected into the response, enabling attacker-controlled Vary values and potentially affecting cache behavior.

Details

The middleware previously copied the Vary header from the request when origin was not set to "*". Since Vary is a response header that should only be managed by the server, this could allow an attacker to influence caching behavior or cause inconsistent CORS handling.

Most environments will see impact only when shared caches or proxies rely on the Vary header. The practical effect varies by configuration.

Impact

May cause cache key pollution and inconsistent CORS enforcement in certain setups. No direct confidentiality, integrity, or availability impact in default configurations.

Resolution

Update to the latest patched release. The CORS middleware has been corrected to handle Vary exclusively as a response header.


Release Notes

honojs/hono (hono)

v4.10.3

Compare Source

Securiy Fix

A security issue in the CORS middleware has been fixed. In some cases, a request header could affect the Vary response header. Please update to the latest version if you are using the CORS middleware.

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.10.2...v4.10.3

v4.10.2

Compare Source

v4.10.1

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.10.0...v4.10.1

v4.10.0

Compare Source

Release Notes

Hono v4.10.0 is now available!

This release brings improved TypeScript support and new utilities.

The main highlight is the enhanced middleware type definitions that solve a long-standing issue with type safety for RPC clients.

Middleware Type Improvements

Imagine the following app:

import { Hono } from 'hono'

const app = new Hono()

const routes = app.get(
  '/',
  (c) => {
    return c.json({ errorMessage: 'Error!' }, 500)
  },
  (c) => {
    return c.json({ message: 'Success!' }, 200)
  }
)

The client with RPC:

import { hc } from 'hono/client'

const client = hc<typeof routes>('/')

const res = await client.index.$get()

if (res.status === 500) {
}

if (res.status === 200) {
}

Previously, it couldn't infer the responses from middleware, so a type error was thrown.

CleanShot 2025-10-17 at 06 51 48@​2x

Now the responses are correctly typed.

CleanShot 2025-10-17 at 06 54 13@​2x

This was a long-standing issue and we were thinking it was super difficult to resolve it. But now come true.

Thank you for the great work @​slawekkolodziej!

cloneRawRequest Utility

The new cloneRawRequest utility allows you to clone the raw Request object after it has been consumed by validators or middleware.

import { cloneRawRequest } from 'hono/request'

app.post('/api', async (c) => {
  const body = await c.req.json()

  // Clone the consumed request
  const clonedRequest = cloneRawRequest(c.req)
  await externalLibrary.process(clonedRequest)
})

Thanks @​kamaal111!

New features

  • feat(types): passing middleware types #​4393
  • feat(ssg): add default plugin that defines the recommended behavior #​4394
  • feat(request): add cloneRawRequest utility for request cloning #​4382

All changes

New Contributors

Full Changelog: honojs/hono@v4.9.12...v4.10.0

v4.9.12

Compare Source

What's Changed

  • refactor: internal structure of PreparedRegExpRouter for optimization and added tests by @​usualoma in #​4456
  • refactor: use protected methods instead of computed properties to allow tree shaking by @​usualoma in #​4458

Full Changelog: honojs/hono@v4.9.11...v4.9.12

v4.9.11

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.9.10...v4.9.11

v4.9.10

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.9.9...v4.9.10

v4.9.9

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.9.8...v4.9.9

v4.9.8

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.9.7...v4.9.8

v4.9.7

Compare Source

Security

  • Fixed an issue in the bodyLimit middleware where the body size limit could be bypassed when both Content-Length and Transfer-Encoding headers were present. If you are using this middleware, please update immediately. Security Advisory

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.9.6...v4.9.7

v4.9.6

Compare Source

Security

Fixed a bug in URL path parsing (getPath) that could cause path confusion under malformed requests.

If you rely on reverse proxies (e.g. Nginx) for ACLs or restrict access to endpoints like /admin, please update immediately.

See advisory for details: GHSA-9hp6-4448-45g2

What's Changed

Full Changelog: honojs/hono@v4.9.5...v4.9.6

v4.9.5

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.9.4...v4.9.5

v4.9.4

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.9.3...v4.9.4

v4.9.3

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.9.2...v4.9.3

v4.9.2

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.9.1...v4.9.2

v4.9.1

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.9.0...v4.9.1

v4.9.0

Compare Source

Release Notes

Hono v4.9.0 is now available!

This release introduces several enhancements and utilities.

The main highlight is the new parseResponse utility that makes it easier to work with RPC client responses.

parseResponse Utility

The new parseResponse utility provides a convenient way to parse responses from Hono RPC clients (hc). It automatically handles different response formats and throws structured errors for failed requests.

import { parseResponse, DetailedError } from 'hono/client'

// result contains the parsed response body (automatically parsed based on Content-Type)
const result = await parseResponse(client.hello.$get()).catch(
  // parseResponse automatically throws an error if response is not ok
  (e: DetailedError) => {
    console.error(e)
  }
)

This makes working with RPC client responses much more straightforward and type-safe.

Thanks @​NamesMT!

New features

  • feat(bun): allow importing upgradeWebSocket and websocket directly #​4242
  • feat(aws-lambda): specify content-type as binary #​4250
  • feat(jwt): add validation for the issuer (iss) claim #​4253
  • feat(jwk): add headerName to JWK middleware #​4279
  • feat(cookie): add generateCookie and generateSignedCookie helpers #​4285
  • feat(serve-static): use join to correct path resolution #​4291
  • feat(jwt): expose utility function verifyWithJwks for external use #​4302
  • feat: add parseResponse util to smartly parse hc's Response #​4314
  • feat(ssg): mark old hook options as deprecated #​4331

All changes

New Contributors

Full Changelog: honojs/hono@v4.8.12...v4.9.0

v4.8.12

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.8.11...v4.8.12

v4.8.11

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.8.10...v4.8.11

v4.8.10

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.8.9...v4.8.10

v4.8.9

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.8.8...v4.8.9

v4.8.8

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.8.7...v4.8.8

v4.8.7

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.8.6...v4.8.7

v4.8.6

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.8.5...v4.8.6

v4.8.5

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.8.4...v4.8.5

v4.8.4

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.8.3...v4.8.4

v4.8.3

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.8.2...v4.8.3

v4.8.2

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.8.1...v4.8.2

v4.8.1

Compare Source

What's Changed

New Contributors

Full Changelog: honojs/hono@v4.8.0...v4.8.1

v4.8.0

Compare Source

Release Notes

Hono v4.8.0 is now available!

This release enhances existing features with new options and introduces powerful helpers for routing and static site generation. Additionally, we're introducing new third-party middleware packages.

  • Route Helper
  • JWT Custom Header Location
  • JSX Streaming Nonce Support
  • CORS Dynamic allowedMethods
  • JWK Allow Anonymous Access
  • Cache Status Codes Option
  • Service Worker fire() Function
  • SSG Plugin System

Plus new third-party middleware:

  • MCP Middleware
  • UA Blocker Middleware
  • Zod Validator v4 Support

Let's look at each of these.

Reduced the code size

First, this update reduces the code size! The smallest hono/tiny package has been reduced by about 800 bytes from v4.7.11, bringing it down to approximately 11 KB. When gzipped, it's only 4.5 KB. Very tiny!

Route Helper

New route helper functions provide easy access to route information and path utilities.

import { Hono } from 'hono'
import {
  matchedRoutes,
  routePath,
  baseRoutePath,
  basePath,
} from 'hono/route'

const api = new Hono()

api.get('/users/:id/posts/:postId', (c) => {
  const matched = matchedRoutes(c) // Array of matched route handlers
  const current = routePath(c) // '/api/users/:id/posts/:postId'
  const base = baseRoutePath(c) // '/api' Base route path
  const appBase = basePath(c) // '/api' Base path
  return c.json({ matched, current, base, appBase })
})

const app = new Hono()
app.route('/api', api)

export default app

These helpers make route introspection cleaner and more explicit.

Thanks @​usualoma!

JWT Custom Header Location

JWT middleware now supports custom header locations beyond the standard Authorization header. You can specify any header name to retrieve JWT tokens from.

import { Hono } from 'hono'
import { jwt } from 'hono/jwt'

const app = new Hono()

app.use(
  '/api/*',
  jwt({
    secret: 'secret-key',
    headerName: 'X-Auth-Token', // Custom header name
  })
)

app.get('/api/protected', (c) => {
  return c.json({ message: 'Protected resource' })
})

This is useful when working with APIs that use non-standard authentication headers.

Thanks @​kunalbhagawati!

JSX Streaming Nonce Support

JSX streaming now supports nonce values for Content Security Policy (CSP) compliance. The streaming context can include a nonce that gets applied to inline scripts.

import { Hono } from 'hono'
import {
  renderToReadableStream,
  Suspense,
  StreamingContext,
} from 'hono/jsx/streaming'

const app = new Hono()

app.get('/', (c) => {
  const stream = renderToReadableStream(
    <html>
      <body>
        <StreamingContext
          value={{ scriptNonce: 'random-nonce-value' }}
        >
          <Suspense fallback={<div>Loading...</div>}>
            <AsyncComponent />
          </Suspense>
        </StreamingContext>
      </body>
    </html>
  )

  return c.body(stream, {
    headers: {
      'Content-Type': 'text/html; charset=UTF-8',
      'Transfer-Encoding': 'chunked',
      'Content-Security-Policy':
        "script-src 'nonce-random-nonce-value'",
    },
  })
})

Thanks @​usualoma!

CORS Dynamic allowedMethods

CORS middleware now supports dynamic allowedMethods based on the request origin. You can provide a function that returns different allowed methods depending on the origin.

import { Hono } from 'hono'
import { cors } from 'hono/cors'

const app = new Hono()

app.use(
  '*',
  cors({
    origin: ['https://example.com', 'https://api.example.com'],
    allowMethods: (origin) => {
      if (origin === 'https://api.example.com') {
        return ['GET', 'POST', 'PUT', 'DELETE']
      }
      return ['GET', 'POST'] // Default for other origins
    },
  })
)

This enables fine-grained control over CORS policies per origin.

Thanks @​Kanahiro!

JWK Allow Anonymous Access

JWK middleware now supports anonymous access with the allow_anon option. When enabled, requests without valid tokens can still proceed to your handlers.

import { Hono } from 'hono'
import { jwk } from 'hono/jwk'

const app = new Hono()

app.use(
  '/api/*',
  jwk({
    jwks_uri: 'https://example.com/.well-known/jwks.json',
    allow_anon: true,
  })
)

app.get('/api/data', (c) => {
  const payload = c.get('jwtPayload')
  if (payload) {
    return c.json({ message: 'Authenticated user', user: payload })
  }
  return c.json({ message: 'Anonymous access' })
})

Additionally, keys and jwks_uri options now support functions that receive the context, enabling dynamic key resolution.

Thanks @​Beyondo!

Cache Status Codes Option

Cache middleware now allows you to specify which status codes should be cached using the cacheableStatusCodes option.

import { Hono } from 'hono'
import { cache } from 'hono/cache'

const app = new Hono()

app.use(
  '*',
  cache({
    cacheName: 'my-cache',
    cacheControl: 'max-age=3600',
    cacheableStatusCodes: [200, 404], // Cache both success and not found responses
  })
)

Thanks @​miyamo2!

Service Worker fire() Function

A new fire() function is available from the Service Worker adapter, providing a cleaner alternative to app.fire().

import { Hono } from 'hono'
import { fire } from 'hono/service-worker'

const app = new Hono()

app.get('/', (c) => c.text('Hello from Service Worker!'))

// Use the standalone fire function
fire(app)

The app.fire() method is now deprecated in favor of this approach. Goodbye app.fire().

SSG Plugin System

Static Site Generation (SSG) now supports a plugin system that allows you to extend the generation process with custom functionality.

For example, the following is easy implementation of a sitemap plugin:

// plugins.ts
import fs from 'node:fs/promises'
import path from 'node:path'
import type { SSGPlugin } from 'hono/ssg'
import { DEFAULT_OUTPUT_DIR } from 'hono/ssg'

export const sitemapPlugin = (baseURL: string): SSGPlugin => {
  return {
    afterGenerateHook: (result, fsModule, options) => {
      const outputDir = options?.dir ?? DEFAULT_OUTPUT_DIR
      const filePath = path.join(outputDir, 'sitemap.xml')
      const urls = result.files.map((file) =>
        new URL(file, baseURL).toString()
      )
      const siteMapText = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.map((url) => `<url><loc>${url}</loc></url>`).join('\n')}
</urlset>`
      fsModule.writeFile(filePath, siteMapText)
    },
  }
}

Applying the plugin:

import { toSSG } from 'hono/ssg'
import { sitemapPlugin } from './plugins'

toSSG(app, fs, {
  plugins: [sitemapPlugin('https://example.com')],
})

Plugins can hook into various stages of the generation process to perform custom actions.

Thanks @​3w36zj6!

Third-party Middleware Updates

In addition to core Hono features, we're excited to introduce new third-party middleware packages that extend Hono's capabilities.

MCP Middleware

A new middleware package @hono/mcp enables creating remote MCP (Model Context Protocol) servers over Streamable HTTP Transport. This is the initial release with more features planned for the future.

import { McpServer } from '@&#8203;modelcontextprotocol/sdk/server/mcp.js'
import { StreamableHTTPTransport } from '@&#8203;hono/mcp'
import { Hono } from 'hono'

const app = new Hono()

// Your MCP server implementation
const mcpServer = new McpServer({
  name: 'my-mcp-server',
  version: '1.0.0',
})

app.all('/mcp', async (c) => {
  const transport = new StreamableHTTPTransport()
  await mcpServer.connect(transport)
  return transport.handleRequest(c)
})

Currently, this is ideal for creating stateless and authentication-less remote MCP servers.

Thanks @​MathurAditya724!

UA Blocker Middleware

The new @hono/ua-blocker middleware allows blocking requests based on user agent headers. It includes blocking AI bots functions.

import { uaBlocker } from '@&#8203;hono/ua-blocker'
import { aiBots } from '@&#8203;hono/ua-blocker/ai-bots'
import { Hono } from 'hono'

const app = new Hono()

// Block specific user agents
app.use(
  '*',
  uaBlocker({
    blocklist: ['ForbiddenBot', 'Not You'],
  })
)

// Block all AI bots
app.use(
  '*',
  uaBlocker({
    blocklist: aiBots,
  })
)

// Serve robots.txt to discourage AI bots
app.use('/robots.txt', useAiRobotsTxt())

Thanks @​finxol!

Zod Validator v4 Support

The @hono/zod-validator middleware now supports Zod v4!

All Changes

New Contributors

Full Changelog: honojs/hono@v4.7.11...v4.8.0

v4.7.11

Compare Source

What's Changed


Configuration

📅 Schedule: Branch creation - "" (UTC), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate bot force-pushed the renovate/npm-hono-vulnerability branch from 1472f27 to 0738333 Compare September 26, 2025 06:58
@renovate renovate bot changed the title fix(deps): update dependency hono to v4.9.7 [security] chore(deps): update dependency hono to v4.9.7 [security] Sep 26, 2025
@renovate renovate bot force-pushed the renovate/npm-hono-vulnerability branch from 0738333 to 4a25621 Compare October 23, 2025 19:37
@renovate renovate bot changed the title chore(deps): update dependency hono to v4.9.7 [security] chore(deps): update dependency hono to v4.10.2 [security] Oct 23, 2025
@renovate renovate bot force-pushed the renovate/npm-hono-vulnerability branch from 4a25621 to 4151a94 Compare October 25, 2025 23:56
@renovate renovate bot changed the title chore(deps): update dependency hono to v4.10.2 [security] chore(deps): update dependency hono to v4.10.3 [security] Oct 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants