Skip to content

fix(deps): update dependency hono to v4.13.16 [security] - #106

Merged
renovate[bot] merged 1 commit into
mainfrom
renovate/npm-hono-vulnerability
Nov 13, 2026
Merged

renovate[bot] merged 1 commit into
mainfrom
renovate/npm-hono-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
hono (source) 4.13.13 → 4.13.16 age confidence

Hono: css helper does not escape a closing tag split between the template and an interpolated value, allowing HTML injection

CVE-2026-126359 / GHSA-3gg2-335m-rxc6

More information

Details

Summary

The css helper in hono/css escapes a / that follows < inside an interpolated value so that a value cannot close the <style> element. The check only looks inside each value. When the text before a value ends with <, whether that is the template itself or an earlier interpolated value, and the next value starts with /, the / is not escaped and the combined output contains an unescaped closing tag.

Details

Interpolated string values are escaped one at a time before they are joined with the surrounding template text. The rule that neutralizes </ therefore cannot see a < that belongs to the template. A template such as a content declaration that opens with a literal < and interpolates a string right after it produces a raw </style> when that string starts with /style>. During server-side rendering the <Style /> element is closed early and the rest of the value is interpreted as HTML.

This issue arises only when < is the last character before an interpolation in a css template, either written in the template or supplied by a preceding value, and the interpolated value is controlled by a client.

Impact

A client that controls such a value can inject HTML, including script, into the page rendered on the server.

This may lead to:

  • Execution of attacker-controlled script in the browser of a user who views the page
  • Exposure of information available to that page

This issue affects applications that interpolate untrusted strings into a css template immediately after a <, including two adjacent interpolations such as ${prefix}${name} where both are untrusted. Other uses of the css helper are not affected.

Workarounds

Do not interpolate untrusted values into css templates, or make sure the text before an interpolated value does not end with <.

Severity

  • CVSS Score: 3.4 / 10 (Low)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Hono: RegExpRouter skips wildcard middleware for some route sets and for paths with an encoded line terminator

CVE-2026-126358 / GHSA-h7mg-cq63-vhpq

More information

Details

Summary

RegExpRouter, which the default SmartRouter selects for most applications, skipped wildcard middleware in three cases, so a route handler ran without the middleware registered for it:

  1. Middleware whose parameter is written with the explicit default pattern, such as /api/:tenant{[^/]+}/admin/*, was not applied to a route written as /api/:tenant/admin/:id. (since 4.13.0)
  2. Middleware on /admin/* was not applied to a route registered on /admin* for paths under /admin/. (since 4.1.4)
  3. For a path with an encoded line terminator (%0A, %0D, %E2%80%A8, %E2%80%A9), no wildcard pattern matched, so the request reached the not-found handler without any wildcard middleware. (since 4.4.0)

TrieRouter, LinearRouter and PatternRouter apply the middleware in all three cases.

Details

RegExpRouter decides at registration time which wildcard middleware covers which route. In cases 1 and 2 it treated patterns that match the same requests as different ones. In case 3 the compiled wildcard did not match line terminators.

The fix derives the coverage from the structure of the registered paths and lets wildcards match line terminators. It also corrects other differences from the other routers (a wildcard in the middle of a path with parameters, duplicate middleware, middleware on static routes), and rejects custom patterns that can match the empty string, such as {[0-9]*}, with UnsupportedPathError. PreparedRegExpRouter data must be regenerated.

Impact

An unauthenticated client can reach a route handler, or the not-found handler, without the authentication or authorization middleware registered on a wildcard path.

This affects applications that use RegExpRouter, directly or through the default SmartRouter, and rely on wildcard middleware for authentication or authorization.

Workarounds

Use new Hono({ router: new TrieRouter() }).

Severity

  • CVSS Score: 5.3 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Hono: mount() and app.mount() can forward a path that bypasses middleware scoped inside the mount prefix

CVE-2026-126357 / GHSA-4m76-xfj5-7975

More information

Details

Summary

mount() and app.mount() remove the mount prefix from the request path and forward the rest to the mounted application. Two mistakes in that step let a crafted request reach a route of the mounted application that the outer application protects with path-scoped middleware, such as an authentication check on /app/admin/*. The outer application routes on the original path, so the middleware does not run.

Details
  1. Dynamic prefix (all affected versions): for a mount such as /api/:tenant/*, the prefix was removed by the length of the route pattern, not of the matched prefix. A request with a longer or shorter first segment is cut in the middle, so /api/a/xxxxx/admin/secret reaches the mounted application as /admin/secret.
  2. Re-normalization (since 4.12.21): the forwarded path was built from the decoded request path and assigned to url.pathname, which turns a decoded backslash into / and collapses ... /app/public%5C..%5Cadmin/secret reaches the mounted application as /admin/secret.

The fix removes the prefix segment by segment from the raw pathname, using the matched parameter values for its length. Route patterns that cannot be handled safely now throw: duplicate parameter names and a wildcard inside the last segment such as /assets*. A trailing slash in an app.mount() prefix no longer removes an extra segment.

Impact

An unauthenticated client can reach a route of a mounted application that the outer application protects with path-scoped middleware.

This affects applications that use mount() or app.mount() and rely on middleware registered on a sub-path inside the mount prefix for authentication or authorization.

Workarounds

Register the authentication middleware inside the mounted application.

Severity

  • CVSS Score: 5.3 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Hono: validator('form') skips validation for multipart/form-data requests with extra parameters

CVE-2026-126356 / GHSA-4h7h-rv7c-7m2v

More information

Details

Summary

validator('form') only recognizes a multipart/form-data Content-Type that carries nothing but a single boundary parameter. A request with another legal parameter, such as charset, or with extra whitespace after the ; is not recognized as a form. The validation callback then receives an empty object, while c.req.parseBody() still parses the body as a form.

Details

The check that decides whether a request body is a form was written as a strict pattern over the whole Content-Type value. Any parameter list that does not look exactly like ; boundary=... fails the check. When it fails, the middleware does not read the body and passes an empty object to the validation callback. If the callback accepts an empty object, the request proceeds to the handler, which can still read all submitted fields through c.req.parseBody() or c.req.formData().

application/x-www-form-urlencoded is not affected. Only the multipart/form-data branch has the strict pattern.

This issue arises when an application relies on validator('form') to reject or restrict fields and the validation callback does not fail on an empty object.

Impact

An unauthenticated client can send form fields that the form validator never sees, by adding a legal parameter to the Content-Type header.

This may lead to:

  • Allow-list or required-field checks in the validator being skipped
  • Fields the application intended to reject reaching the handler

This issue affects applications that use validator('form') with multipart/form-data requests and whose validation callback accepts an empty object.

Workarounds

Reject an empty object in the validator('form') callback, or validate the result of await c.req.parseBody() in the handler.

Severity

  • CVSS Score: 5.3 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Hono: csrf() does not check requests sent by hyperlink auditing (text/ping)

CVE-2026-126355 / GHSA-46wx-v44x-9hh2

More information

Details

Summary

csrf() validates a request only when its Content-Type is one of the three types an HTML form can send. Chromium's hyperlink auditing (<a ping>) sends a cross-origin POST with the user's cookies and the content type text/ping, which is not in that list. The middleware does not look at Origin or Sec-Fetch-Site for such a request, so it is passed to the handler.

Details

The middleware skips the origin check when the content type is not one that a form submission produces. The assumption was that any other content type requires a CORS preflight and therefore cannot be sent cross-origin with credentials. Hyperlink auditing is an exception: Chrome and Edge send the ping as a credentialed POST without a preflight, with a fixed body and Content-Type: text/ping.

A page on another origin can therefore trigger a POST to any URL of the application. The csrf() options for origin and secFetchSite do not change the outcome, because neither header is evaluated for the request.

The request body is fixed, so only actions whose effect does not depend on the body can be triggered. Firefox does not send pings by default. As with any CSRF, the user's cookie must be sent with the request, which with the default SameSite=Lax means a same-site origin or a cookie set with SameSite=None.

Impact

A user who visits a malicious page in Chrome or Edge while logged in to an application protected by csrf() can be made to send a state-changing request to that application, such as logging out, deleting a resource, or toggling a setting that is selected by the path or query string.

This issue affects applications that rely on csrf() as their CSRF protection and expose state-changing endpoints whose effect does not depend on the request body.

Workarounds

Reject requests with a Content-Type of text/ping in a middleware registered before csrf(), or set session cookies with SameSite=Strict.

Severity

  • CVSS Score: 5.3 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:H/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

honojs/hono (hono)

v4.13.16

Compare Source

Security fixes

This release includes fixes for the following security issues:

mount() and app.mount() can forward a path that bypasses middleware scoped inside the mount prefix

Affects: mount() in hono/mount and app.mount(). A dynamic prefix such as /api/:tenant/* was removed by the length of the route pattern. The forwarded path was also re-normalized by the URL parser, so a decoded \ became / and .. collapsed. Both let a crafted request skip middleware scoped inside the mount prefix. Routes such as /assets* and duplicate parameter names now throw. GHSA-4m76-xfj5-7975

RegExpRouter skips wildcard middleware for certain route patterns and for paths with an encoded line terminator

Affects: RegExpRouter, including the default SmartRouter. Wildcard middleware was not applied in three cases: a parameter written as {[^/]+} in the middleware path only, a /prefix* route next to /prefix/* middleware, and a path with an encoded line terminator. RegExpRouter now covers the same routes as the other routers. Custom patterns that can match the empty string, such as {[0-9]*}, throw UnsupportedPathError. Regenerate PreparedRegExpRouter data. GHSA-h7mg-cq63-vhpq

validator('form') skips validation for multipart/form-data requests with extra parameters

Affects: validator('form') in hono/validator. A multipart/form-data request with an extra parameter such as charset was not recognized as a form. The validator then saw an empty object while the handler could read all fields. GHSA-4h7h-rv7c-7m2v

css helper does not escape a closing tag assembled from template parts and values, allowing HTML injection

Affects: css in hono/css. A </style> split between the template and a value, or between two values, was not escaped. Closing tags are now escaped after minification. GHSA-3gg2-335m-rxc6

csrf() does not check requests sent by hyperlink auditing (text/ping)

Affects: csrf() in hono/csrf. A POST sent by Chromium's <a ping> has the content type text/ping and was not checked against Origin and Sec-Fetch-Site. GHSA-46wx-v44x-9hh2


Users who rely on path-scoped middleware with mount(), wildcard middleware with the default router, validator('form'), the css helper with untrusted values, or csrf() are strongly encouraged to upgrade to this version.

What's Changed

  • fix(jwt): reject a signature segment outside the base64url alphabet and a header with crit in #​5597

Full Changelog: honojs/hono@v4.13.15...v4.13.16

v4.13.15

Compare Source

What's Changed

Full Changelog: honojs/hono@v4.13.14...v4.13.15

v4.13.14

Compare Source

What's Changed

  • docs(contributing): ask for issues instead of RPs #​5526
  • docs(readme): sync the contributing list with CONTRIBUTING.md #​5527
  • fix(adapters): accept Hono v5 prereleases in the hono peer range #​5537
  • chore: unified oxfmt and oxlint config #​5518
  • docs(readme): remove the deepwiki badge #​5548
  • fix(serve-static): only serve GET and HEAD requests #​5514
  • fix(build): keep barrel imports in the bundled d.ts #​5557
  • fix(jsx): preserve self-closing void elements in cloneElement #​5314
  • fix(css): keep "//" inside an unquoted url() when minifying #​5450
  • fix(css): keep the descendant combinator before a pseudo-class when minifying #​5451
  • fix(serve-static): respect q-values in Accept-Encoding for precompressed files #​5436
  • fix(helper/route): match regex params in basePath() the same way as the router #​5498
  • fix(trie-router): keep first value for duplicate path params #​5423
  • fix(hono-base): disallow getPath when strict is false #​5563
  • fix(css): Fix multiline CSS handling in style replacement #​5405
  • feat(bearer-auth): allow MessageFunction to return a Response #​5269
  • fix(utils/url): preserve encoded duplicate query order #​5495

Full Changelog: honojs/hono@v4.13.13...v4.13.14


Configuration

📅 Schedule: (in timezone America/Chicago)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

♻ Rebasing: Whenever PR is behind base branch, 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 added the security label Nov 13, 2026
@renovate
renovate Bot enabled auto-merge (squash) November 13, 2026 00:58
@renovate
renovate Bot merged commit 5fb901a into main Nov 13, 2026
4 checks passed
@renovate
renovate Bot deleted the renovate/npm-hono-vulnerability branch November 13, 2026 01:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

0 participants