-Infinity
0
Severity
3.7
Infoleak
AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N

Summary

The Proxy Helper (hono/proxy) does not remove response headers named by the origin's Connection header. Headers that the origin marked as connection-scoped are therefore forwarded to clients.

Details

Per RFC 9110 Section 7.6.1, an intermediary must remove the header fields listed in a message's Connection header field before forwarding the message, in addition to the well-known hop-by-hop headers. The proxy() function removed the well-known hop-by-hop headers (including Connection itself) from origin responses, but did not remove the headers that the response's Connection header field designated as connection-scoped.

This issue arises when an application proxies responses from an origin that declares additional, non-standard headers as hop-by-hop via the Connection response header.

Impact

A client may receive response headers that the origin intended only for its immediate peer. This may lead to:

- Disclosure of connection-scoped or internal metadata contained in such headers

This issue affects applications that use the Proxy Helper (hono/proxy) to forward responses from origins that list custom header names in their Connection response header. Applications whose origins only use the standard hop-by-hop headers are not affected.

1 / 2
Source: GitHub
First published (updated )
Severity
6.3
AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N

Hono before 4.12.7 allows proto key in parseBody with dot option enabled, permitting specially crafted form field names to create objects with proto properties. When parsed results are merged into regular JavaScript objects using unsafe merge patterns, attackers can exploit this to achieve prototype pollution and modify object behavior.

First published (updated )
Severity
6.1
XSS
AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N

Summary

cx() in hono/css composes class names from plain strings but marks the result as already-escaped without HTML-escaping the input. When the result is used as a JSX class attribute during server-side rendering, the value is written into the attribute unescaped, so untrusted input can break out of the class attribute and inject arbitrary markup, leading to Cross-Site Scripting (XSS).

Details

Because the composed value is treated as pre-escaped, the HTML attribute escaping normally applied to interpolated values is skipped, and characters such as " pass through unescaped — allowing a value to terminate the attribute and add further attributes or elements. This arises when an application passes untrusted, user-controlled input as a class name to cx(), for example when merging a base class with an externally provided className.

Impact

During server-side rendering, an attacker who controls a value passed to cx() can inject arbitrary HTML into the page, resulting in stored or reflected XSS in the victim's browser.

This may lead to:

- Execution of attacker-controlled script in the victim's browser session. - Session hijacking, credential theft, or actions performed on behalf of the victim.

Applications are affected only if they render JSX server-side and pass untrusted input as a class name to cx().

1 / 2
Source: GitHub
First published (updated )
Severity
6.5
Race Condition
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N

Summary

hono/jsx did not isolate context values per request during server-side rendering. While an async component was suspended on await, its provided context value stayed observable to other requests rendering concurrently, so useContext() could return a value from a different in-flight request.

Details

During server-side rendering, context values were kept in a process-wide structure rather than scoped to each request's render. While an async component awaited, another request entering the same provider could observe or replace the value; when the first render resumed, it could read the other request's context.

This affects the usual ways request-scoped data is passed through a server-rendered JSX tree:

- createContext() / useContext() - the jsxRenderer middleware and useRequestContext()

It arises only when context is read after an await inside an async component while requests render concurrently. Reading context synchronously (before any await), purely synchronous rendering, and client-side (DOM) rendering are not affected.

Impact

Under concurrent requests, a response could be rendered with another request's context. A user may receive HTML rendered for a different user, and an authorization check performed after an await may be evaluated against another user's data.

This may lead to:

- disclosure of rendered output intended for another user - authorization decisions made with the wrong request's context - cross-request mixing of session or other request-scoped state

1 / 2
Source: GitHub
First published (updated )
Severity
5.3
AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N

Summary

The AWS API Gateway v1 adapter can drop a distinct repeated request header value. When a header appears multiple times, the adapter de-duplicates values using a substring comparison instead of an exact match, so a value that is a substring of another value of the same header is omitted (for example, 203.0.113.1 is dropped when another value is 203.0.113.10).

Details

A repeated request header carries an ordered list of values. Middleware or application logic that depends on the complete list — such as IP restriction that walks the X-Forwarded-For chain, rate limiting, audit logging, or proxy-chain validation — can therefore receive incomplete data that differs from what the client actually sent.

This issue arises on deployments using the AWS API Gateway v1 adapter (the same pattern also affects the VPC Lattice adapter), for requests that contain the same header more than once.

Impact

An attacker can craft repeated header values so that one value is omitted before the application sees the request. Where a security or routing decision relies on the full chain, this can alter that decision.

This affects applications deployed through Hono's AWS API Gateway v1 (or VPC Lattice) adapter that rely on the complete set of repeated request header values.

1 / 2
Source: GitHub
First published (updated )
Severity
6.9
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N

Hono before 4.10.2 (fixed in 4.10.3) contains a flaw in its CORS middleware: when the origin is not set to "", the middleware copies the Vary header from the incoming request into the response. Because Vary is a response header that should be managed by the server, an attacker can supply arbitrary Vary values that are reflected into the response, potentially causing cache key pollution and inconsistent CORS enforcement in environments that rely on shared caches or proxies.

First published (updated )
Severity
5.3
XSS
AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N

hono before 4.12.14 contains an html injection vulnerability in jsx server-side rendering that allows attackers to inject unintended html by using malformed attribute names. Attackers can craft specially crafted attribute keys containing characters like quotes or angle brackets to break html tag boundaries and inject arbitrary attributes or elements.

First published (updated )
Severity
6.5
AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N

Summary

The jwt and jwk middlewares do not verify that the Authorization header value uses theBearer scheme. Any two-part header value — regardless of the scheme name in the first position — proceeds to JWT verification. A request presenting a valid JWT under a non-Bearer scheme identifier (such as Basic or Token) is authenticated identically to a correctly formed Bearer request.

Details

When processing an Authorization (or custom) header, the middleware splits the value on whitespace and uses the second token as the JWT to verify. It does not check that the first token is bearer (case-insensitively). RFC 6750 specifies that JWT bearer tokens must be presented using the Bearer scheme; other scheme identifiers carry distinct semantics and may be subject to different policies in network-layer security controls.

This discrepancy means that scheme-aware external controls — such as WAF rules, API gateways, or reverse proxies that apply policies specific to the Bearer scheme identifier — can be bypassed by presenting a valid JWT under a different scheme name.

This issue affects hono/jwt and hono/jwk middleware.

Impact

An attacker who possesses a valid JWT may present it under a non-Bearer scheme identifier and still pass middleware authentication.

This may lead to:

- Bypass of network-layer security controls that inspect or filter requests based on the authorization scheme identifier - Token reuse across authentication schemes in applications that use multiple authorization mechanisms

This issue affects applications where hono/jwt or hono/jwk authentication is combined with external controls that enforce scheme-based access policies.

1 / 2
Source: GitHub
First published (updated )
Severity
5.3
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N

Summary

The ip-restriction middleware (hono/ip-restriction) compares incoming IP addresses against configured deny and allow rules using string equality after partial normalization. Non-canonical IPv6 representations of an address already listed in a static rule — such as compressed forms, explicit-zero forms, or hex-notation IPv4-mapped addresses — do not match the normalized rule entry, causing the rule to be silently skipped.

Details

When the rule matcher is built, each configured IP rule is normalized to a canonical string form. Incoming IP addresses received at request time are then compared against those canonical strings without applying the same normalization. Because IPv6 permits multiple syntactically different representations of the same numeric address, a non-canonical form of a denied address fails the string lookup and proceeds to the CIDR check, which also finds no match for rules registered as static (no prefix length). The request is then allowed.

Affected non-canonical forms include:

- Compressed versus expanded notation (2001:db8::1 vs 2001:db8:0:0:0:0:0:1) - Hex-notation IPv4-mapped addresses (::ffff:7f00:1 vs ::ffff:127.0.0.1) - Zone identifier suffixes (e.g., fe80::1%eth0)

Additionally, invalid IP address strings provided as the remote address are not rejected and may result in unexpected allow or deny behavior.

This issue arises when applications use ipRestriction() with static (non-CIDR) rules and the IP address source can supply addresses in non-canonical IPv6 form.

Impact

A request from an IP address covered by a static deny rule may bypass the restriction if the address is presented in a non-canonical IPv6 form.

This may lead to:

- Unauthorized access to endpoints intended to be restricted to specific IP addresses - Bypass of IP-based access controls in environments where the runtime or an upstream proxy provides source addresses in a form that differs from the canonical form used in the rule configuration

This issue affects applications using hono/ip-restriction with static deny rules for IPv4 or IPv6 addresses, particularly when the source address is derived from proxy headers or custom getIP implementations that may return non-canonical forms.

1 / 2
Source: GitHub
First published (updated )
Severity
5.3
AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N

Summary

The serialize() function in hono/cookie validates domain and path options against characters that corrupt Set-Cookie header syntax (;, \r, \n), but does not apply the same validation to sameSite and priority. An application that passes user-controlled input into either option may produce a Set-Cookie response header containing attacker-chosen additional attributes.

Details

When constructing a Set-Cookie header value, serialize() appends the sameSite and priority option values directly into the output string after a presentation-only transformation (capitalizing the first character). Although the TypeScript type signature constrains these options to specific string literals, that constraint is not enforced at runtime; any string value, including one containing ; or line-feed characters, passes through unchanged.

The validation guard that rejects ;, \r, and \n from domain and path is not applied to sameSite or priority. An application that passes a request-derived value to either option therefore provides an injection point into the header line.

This issue arises when an application passes user-controlled input to the sameSite or priority option of setCookie() or serialize().

Impact

An attacker who can control the sameSite or priority option value may inject additional attributes into a Set-Cookie response header.

This may lead to:

- Cookie attribute injection — overriding Domain, Path, HttpOnly, Secure, or Max-Age for the affected cookie - HTTP response header injection on runtimes that do not strictly validate header values, enabling a second attacker-controlled Set-Cookie header in the same response

This issue affects applications that pass user-derived input into the sameSite or priority option of hono/cookie serialization functions.

1 / 2
Source: GitHub
First published (updated )
Severity
5.3
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

Summary

app.mount() strips the mount prefix from the incoming request path using the raw URL pathname, while route matching is performed against the percent-decoded path. This inconsistency causes the prefix to be stripped at the wrong position when the path contains percent-encoded multi-byte characters, resulting in the mounted sub-application receiving an incorrect path.

Details

When app.mount(prefix, subApp) is called, Hono calculates the number of characters to strip based on the decoded mount prefix length, but then applies that slice to the raw URL pathname. When the URL contains percent-encoded characters that expand to fewer characters when decoded (such as encoded non-ASCII characters), the two representations have different lengths, so the prefix is stripped at the wrong byte offset.

As a result, the sub-application receives a path that does not correspond to the intended sub-path — it may receive a partial or garbled path instead of the expected value after the mount prefix is removed.

This issue arises when an application uses app.mount() with paths that contain percent-encoded characters, particularly when the mount prefix itself or the request path contains encoded non-ASCII characters.

Impact

A mounted sub-application may receive an incorrectly stripped path, causing requests to be routed to unintended handlers within the sub-application.

This may lead to:

- Middleware or route handlers in the sub-application being bypassed or incorrectly matched due to the malformed path - Requests reaching sub-application routes that the developer did not intend to be accessible via the mounted path

This issue affects applications that use app.mount() where the request URL may contain percent-encoded characters in the mount prefix or subsequent path segments.

1 / 2
Source: GitHub
First published (updated )
Severity
4.3
AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N

Summary

The JSX renderer escapes style attribute object values for HTML but not for CSS. Untrusted input in a style object value or property name can therefore inject additional CSS declarations into the rendered style attribute. The impact is limited to CSS and does not allow JavaScript execution or HTML attribute breakout.

Details

style object values are serialized into a CSS declaration list and escaped for HTML attribute context only. Characters that act as CSS declaration boundaries — such as ;, comment markers, quoted strings, and block delimiters — are valid in HTML attribute content and can extend a value beyond its assigned property.

This issue arises when untrusted input is interpolated into a JSX style object and rendered server-side.

Impact

An attacker who can control the value or property name of a style object may inject arbitrary CSS declarations. This may lead to:

- Visual manipulation of the page, including full-viewport overlays usable for phishing - Outbound requests to attacker-controlled hosts via CSS resource references such as url(...) - Hijacking of UI affordances through layout, positioning, or visibility changes

This issue affects applications that render JSX on the server with style object values or property names derived from untrusted input.

1 / 2
Source: GitHub
First published (updated )
Severity
3.8
AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:N

Summary

Improper validation of the JWT NumericDate claims exp, nbf, and iat in hono/utils/jwt allows tokens with non-spec-compliant claim values to silently bypass time-based checks. This issue is not exploitable by an anonymous attacker; it only manifests when a malformed claim value reaches verify() — typically when the application itself issues such tokens, or when the signing key is otherwise under attacker control.

Details

The validation routine combined option, presence, and threshold checks in a single short-circuiting expression, so several classes of malformed values were silently skipped instead of rejected:

- A falsy numeric value short-circuited the presence check. - A non-finite numeric value compared as never-after-now and never-expired. - A non-numeric type produced NaN comparisons that evaluated false.

This deviates from RFC 7519 §4.1.4, which defines NumericDate as a finite JSON numeric value.

Impact

An actor able to issue tokens accepted by the application may craft tokens whose exp, nbf, or iat claims silently bypass time-based enforcement. This may lead to:

- Tokens treated as never expiring even with exp configured on the verifier. - Tokens with a future nbf accepted as currently valid. - Tokens with a future iat accepted as legitimately issued.

Deployments using a well-formed token issuer and protecting the signing key are not affected.

1 / 2
Source: GitHub
First published (updated )
Severity
5.3
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

Summary

Cache Middleware does not skip caching for responses that declare per-user variance via Vary: Authorization or Vary: Cookie. As a result, a response cached for one authenticated user may be served to subsequent requests from different users.

Details

The Cache Middleware skips caching when a response carries Vary: , certain Cache-Control directives (private, no-store, no-cache), or Set-Cookie. However, Vary: Authorization and Vary: Cookie — the standard signals defined in RFC 9110 / RFC 9111 to indicate per-user responses — are not treated as cache-skip reasons.

This issue arises when applications use the Cache Middleware on endpoints that return user-specific data and rely on Vary: Authorization or Vary: Cookie to scope the response per user, without also setting Cache-Control: private.

Impact

A user may receive a cached response that was originally generated for a different authenticated user. This may lead to:

- Disclosure of personally identifiable information or other user-specific data present in the response body - Inconsistent or incorrect behavior in user-specific endpoints

This issue affects applications that use the Cache Middleware on endpoints whose responses vary by Authorization or Cookie and that do not also set Cache-Control: private.

1 / 2
Source: GitHub
First published (updated )
Severity
6.5
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N

Summary

bodyLimit() does not reliably enforce maxSize for requests without a usable Content-Length (e.g. Transfer-Encoding: chunked). Oversized requests can reach handlers and return 200 instead of 413.

Details

For chunked / unknown-length requests, bodyLimit() wraps the body in a stream that counts bytes asynchronously, then runs the handler before the size decision is final. The 413 is only applied afterwards by checking c.error.

This lets the limit be bypassed when:

- the handler does not read the body, - the handler reads only the first chunk(s) and returns, or - the handler reads the body but swallows the read error in try/catch.

In all three cases the handler returns 200 before the limit check completes (or its result is observed).

The fix is to enforce the size decision before next() runs, instead of retrofitting the response via c.error afterwards.

Impact

Applications relying on bodyLimit() as a hard boundary can be bypassed: oversized chunked requests can reach handler logic and return successful responses. Per-request data exposure is bounded by maxSize, but the documented guarantee — "oversized requests are rejected before business logic runs" — does not hold.

Credits

- @lalalala5678 (slow chunked / early return variants) - @Jvr2022 (error handling bypass)

1 / 2
Source: GitHub
First published (updated )
Severity
6.1
XSS
AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:L/A:N

Summary

Improper handling of JSX element tag names in hono/jsx allowed unvalidated tag names to be directly inserted into the generated HTML output.

When untrusted input is used as a tag name via the programmatic jsx() or createElement() APIs during server-side rendering, specially crafted values may break out of the intended element context and inject unintended HTML.

Details

When rendering JSX elements to HTML strings, attribute values are escaped and attribute names are validated. However, element tag names were previously inserted into the output without validation.

If a tag name contains characters such as <, >, quotes, or whitespace, it may alter the structure of the generated HTML.

For example, malformed tag names can:

Break out of the intended element and introduce unintended HTML elements Inject attributes or event handlers into the rendered output

This issue arises when untrusted input (such as query parameters or database content) is used as JSX tag names via jsx() or createElement() during server-side rendering.

Impact

An attacker who can control tag names used in JSX rendering may inject unintended HTML into the generated output.

This may lead to:

Injection of unexpected HTML elements or attributes Corruption of the HTML structure Cross-site scripting (XSS) when combined with unsafe usage patterns

This issue only affects applications that construct JSX tag names from untrusted input. Applications using static or allowlisted tag names are not affected.

1 / 2
Source: GitHub
First published (updated )
Severity
4.8
Input Validation
AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N

Summary

A discrepancy between browser cookie parsing and parse() handling allows cookie prefix protections to be bypassed.

Cookie names that are treated as distinct by the browser may be normalized to the same key by parse(), allowing attacker-controlled cookies to override legitimate ones.

Details

Browsers follow RFC 6265bis and only trim SP (0x20) and HTAB (0x09) from cookie names. Other characters, such as the non-breaking space (U+00A0), are preserved as part of the cookie name.

For example, the browser treats the following cookies as distinct:

"dummy-cookie" "\u00a0dummy-cookie"

However, parse() previously used JavaScript's trim(), which removes a broader set of characters including U+00A0. As a result, both names are normalized to:

"dummy-cookie"

This mismatch allows attacker-controlled cookies with a U+00A0 prefix to shadow or override legitimate cookies when accessed via getCookie().

Impact

An attacker who can set cookies (e.g., via a man-in-the-middle on a non-secure page or other injection vector) can bypass cookie prefix protections and override sensitive cookies.

This may lead to:

Bypassing Secure- and Host- prefix protections Overriding cookies that rely on the Secure attribute Session fixation or session hijacking depending on application usage

This issue affects applications that rely on getCookie() for security-sensitive cookie handling.

1 / 2
Source: GitHub
First published (updated )
Severity
6.3
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Summary

ipRestriction() does not canonicalize IPv4-mapped IPv6 client addresses (e.g. ::ffff:127.0.0.1) before applying IPv4 allow or deny rules. In environments such as Node.js dual-stack, this can cause IPv4 rules to fail to match, leading to unintended authorization behavior.

Details

The middleware classifies client addresses based on their textual form. Addresses containing ":" are treated as IPv6, including IPv4-mapped IPv6 addresses such as ::ffff:127.0.0.1. These addresses are not normalized to IPv4 before matching.

As a result:

IPv4 static rules (e.g. 127.0.0.1) do not match because the raw string differs IPv4 CIDR rules (e.g. 127.0.0.0/8, 10.0.0.0/8) are skipped because the address is treated as IPv6

For example, with:

denyList: ['127.0.0.1']

a request from 127.0.0.1 may be represented as ::ffff:127.0.0.1 and bypass the deny rule.

This behavior commonly occurs in Node.js environments where IPv4 clients are exposed as IPv4-mapped IPv6 addresses.

Impact

Applications that rely on IPv4-based ipRestriction() rules may incorrectly allow or deny requests.

In affected deployments, a denied IPv4 client may bypass access restrictions. Conversely, legitimate clients may be rejected when using IPv4 allow lists.

1 / 2
Source: GitHub
First published (updated )
Severity
5.9
Path Traversal
CVSS:4.0/AV:L/AC:H/AT:P/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Summary

A path traversal issue in toSSG() allows files to be written outside the configured output directory during static site generation. When using dynamic route parameters via ssgParams, specially crafted values can cause generated file paths to escape the intended output directory.

Details

The static site generation process creates output files based on route paths derived from application routes and parameters. When ssgParams is used to provide values for dynamic routes, those values are used to construct output file paths. If these values contain traversal sequences (e.g. ..), the resulting output path may resolve outside the configured output directory. As a result, files may be written to unintended locations instead of being confined within the specified output directory.

For example: ts import { Hono } from 'hono' import { toSSG, ssgParams } from 'hono/ssg'

const app = new Hono()

app.get('/:id', ssgParams([{ id: '../pwned' }]), (c) => { return c.text('pwned') })

toSSG(app, fs, { dir: './static' })

In this case, the generated output path may resolve outside ./static, resulting in a file being written outside the intended output directory.

Impact

An attacker who can influence values passed to ssgParams during the build process may be able to write files outside the intended output directory.

Depending on the build and deployment environment, this may:

overwrite unintended files affect generated artifacts impact deployment outputs or downstream tooling

This issue is limited to build-time static site generation and does not affect request-time routing.

1 / 2
Source: GitHub
First published (updated )
Severity
5.3
Path Traversal
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

Summary

A path handling inconsistency in serveStatic allows protected static files to be accessed by using repeated slashes (//) in the request path.

When route-based middleware (e.g., /admin/) is used for authorization, the router may not match paths containing repeated slashes, while serveStatic resolves them as normalized paths. This can lead to a middleware bypass.

Details

The routing layer and serveStatic handle repeated slashes differently.

For example:

/admin/secret.txt => matches /admin/ /admin//secret.txt => may not match /admin/

However, serveStatic may interpret both paths as the same file location (e.g., admin/secret.txt) and return the file.

This inconsistency allows a request such as:

GET //admin/secret.txt

to bypass middleware registered on /admin/ and access protected files.

The issue has been fixed by rejecting paths that contain repeated slashes, ensuring consistent behavior between route matching and static file resolution.

Impact

An attacker can access static files that are intended to be protected by route-based middleware by using repeated slashes in the request path.

This can lead to unauthorized access to sensitive files under the static root.

This issue affects applications that rely on serveStatic together with route-based middleware for access control.

1 / 2
Source: GitHub
First published (updated )
Severity
5.3
Path Traversal
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

@hono/node-server allows running the Hono application on Node.js. Prior to 1.19.13, a path handling inconsistency in serveStatic allows protected static files to be accessed by using repeated slashes (//) in the request path. When route-based middleware (e.g., /admin/) is used for authorization, the router may not match paths containing repeated slashes, while serveStatic resolves them as normalized paths. This can lead to a middleware bypass. This vulnerability is fixed in 1.19.13.

1 / 2
Source: MITRE
First published (updated )
Severity
7.5
EPSS
0.04%
Path Traversal
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

@hono/node-server allows running the Hono application on Node.js. Prior to version 1.19.10, when using @hono/node-server's static file serving together with route-based middleware protections (e.g. protecting /admin/), inconsistent URL decoding can allow protected static resources to be accessed without authorization. In particular, paths containing encoded slashes (%2F) may be evaluated differently by routing/middleware matching versus static file path resolution, enabling a bypass where middleware does not run but the static file is still served. This issue has been patched in version 1.19.10.

1 / 2
Source: MITRE
First published (updated )
Severity
5.4
EPSS
0.03%
AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N

Summary

The setCookie() utility did not validate semicolons (;), carriage returns (\r), or newline characters (\n) in the domain and path options when constructing the Set-Cookie header.

Because cookie attributes are delimited by semicolons, this could allow injection of additional cookie attributes if untrusted input was passed into these fields.

Details

setCookie() builds the Set-Cookie header by concatenating option values. While the cookie value itself is URL-encoded, the domain and path options were previously interpolated without rejecting unsafe characters.

Including ;, \r, or \n in these fields could result in unintended additional attributes (such as SameSite, Secure, Domain, or Path) being appended to the cookie header.

Modern runtimes prevent full header injection via CRLF, so this issue is limited to attribute-level manipulation within a single Set-Cookie header.

The issue has been fixed by rejecting these characters in the domain and path options.

Impact

An attacker may be able to manipulate cookie attributes if an application passes user-controlled input directly into the domain or path options of setCookie().

This could affect cookie scoping or security attributes depending on browser behavior. Exploitation requires application-level misuse of cookie options.

1 / 2
Source: GitHub
First published (updated )
Severity
6.5
EPSS
0.05%
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N

Summary

When using streamSSE() in Streaming Helper, the event, id, and retry fields were not validated for carriage return (\r) or newline (\n) characters.

Because the SSE protocol uses line breaks as field delimiters, this could allow injection of additional SSE fields within the same event frame if untrusted input was passed into these fields.

Details

The SSE helper builds event frames by joining lines with \n. While multi-line data: fields are handled according to the SSE specification, the event, id, and retry fields previously allowed raw values without rejecting embedded CR/LF characters.

Including CR/LF in these control fields could allow unintended additional fields (such as data:, id:, or retry:) to be injected into the event stream.

The issue has been fixed by rejecting CR/LF characters in these fields.

Impact

An attacker could manipulate the structure of SSE event frames if an application passed user-controlled input directly into event, id, or retry.

Depending on application behavior, this could result in injected SSE fields or altered event stream handling. Applications that render e.data in an unsafe manner (for example, using innerHTML) could potentially expose themselves to client-side script injection.

This issue affects applications that rely on the SSE helper to enforce protocol-level constraints.

1 / 2
Source: GitHub
First published (updated )
Severity
9.8
EPSS
0.04%
Path Traversal
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

Summary

When using serveStatic together with route-based middleware protections (e.g. app.use('/admin/', ...)), inconsistent URL decoding allowed protected static resources to be accessed without authorization.

The router used decodeURI, while serveStatic used decodeURIComponent. This mismatch allowed paths containing encoded slashes (%2F) to bypass middleware protections while still resolving to the intended filesystem path.

Details

The routing layer preserved %2F as a literal string, while serveStatic decoded it into / before resolving the file path.

Example:

Request: /admin%2Fsecret.html

- Router sees: /admin%2Fsecret.html → does not match /admin/ - Static handler resolves: /admin/secret.html

As a result, static files under the configured static root could be served without triggering route-based protections.

This only affects applications that both:

- Protect subpaths using route-based middleware, and - Serve files from the same static root using serveStatic.

This does not allow access outside the static root and is not a path traversal vulnerability.

Impact

An unauthenticated attacker could bypass route-based authorization for protected static resources by supplying paths containing encoded slashes.

Applications relying solely on route-based middleware to protect static subpaths may have exposed those resources.

1 / 2
Source: GitHub
First published (updated )
Severity
8.2
EPSS
0.02%
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N

Summary

When using the AWS Lambda adapter (hono/aws-lambda) behind an Application Load Balancer (ALB), the getConnInfo() function incorrectly selected the first value from the X-Forwarded-For header.

Because AWS ALB appends the real client IP address to the end of the X-Forwarded-For header, the first value can be attacker-controlled.

This could allow IP-based access control mechanisms (such as the ipRestriction middleware) to be bypassed.

Details

In ALB environments, AWS appends the actual client IP address to the end of any existing X-Forwarded-For header value. However, the previous implementation of getConnInfo() extracted the leftmost IP address:

ts address = xff.split(',')[0].trim()

If a client sent:

X-Forwarded-For: <spoofed-ip>

ALB would forward:

X-Forwarded-For: <spoofed-ip>, <real-client-ip>

Since the implementation selected the first value, the spoofed IP address was trusted. This affected applications using:

ts ipRestriction(getConnInfo, { allowList: [...] })

or any custom middleware relying on getConnInfo(c).remote.address for authorization decisions.

The issue only affects deployments using the AWS Lambda adapter behind an ALB. API Gateway (v1/v2) and Lambda Function URLs are not affected, as they use AWS-provided source IP values from requestContext.

Impact

An unauthenticated remote attacker could bypass IP-based access restrictions by supplying a crafted X-Forwarded-For header. This may allow access to resources that were intended to be restricted by IP address.

Only applications deployed behind an ALB and relying on getConnInfo() for IP-based authorization are affected.

1 / 2
Source: GitHub
First published (updated )
Severity
4.7
EPSS
0.04%
XSS
AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:L/A:N

Summary

A Cross-Site Scripting (XSS) vulnerability exists in the ErrorBoundary component of the hono/jsx library. Under certain usage patterns, untrusted user-controlled strings may be rendered as raw HTML, allowing arbitrary script execution in the victim's browser.

Details

The issue is in the ErrorBoundary component (src/jsx/components.ts). ErrorBoundary previously forced certain rendered output paths to be treated as raw HTML, bypassing the library's default escaping behavior. This could result in unescaped rendering when developers pass user-controlled strings directly as children, or when fallbackRender returns user-controlled strings (for example, reflecting error messages that contain attacker input).

This vulnerability is only exploitable when an application renders untrusted user input within ErrorBoundary without appropriate escaping or sanitization.

Impact

Successful exploitation may allow attackers to execute arbitrary JavaScript in the victim’s browser (reflected XSS). Depending on the application context, this can lead to actions such as session compromise, data exfiltration, or performing unauthorized actions as the victim.

Affected Components

hono/jsx: ErrorBoundary component

1 / 2
Source: GitHub
First published (updated )
Severity
6.3
EPSS
0.01%
Infoleak
CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Summary

Serve static Middleware for the Cloudflare Workers adapter contains an information disclosure vulnerability that may allow attackers to read arbitrary keys from the Workers environment. Improper validation of user-controlled paths can result in unintended access to internal asset keys.

Details

The vulnerability exists in the serve-static middleware used with the Cloudflare Workers adapter. When serving static assets, the middleware does not sufficiently validate or restrict user-supplied paths before resolving them against the Workers asset storage.

As a result, an attacker may craft requests that access arbitrary keys beyond the intended static asset scope. This issue only affects applications running on Cloudflare Workers that use Serve static Middleware with user-controllable request paths.

Impact

This vulnerability may lead to information disclosure by allowing unauthorized access to internal assets or data stored in the Workers environment. The exposed data is limited to readable asset keys and does not allow modification of stored data or execution of arbitrary code.

The impact is limited to applications that use Serve static Middleware in the Cloudflare Workers adapter and rely on it to safely handle untrusted request paths.

Affected Components

Serve static Middleware (Cloudflare Workers adapter)

1 / 2
Source: GitHub
First published (updated )
Severity
5.3
EPSS
0.01%
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

Summary

Cache Middleware contains an information disclosure vulnerability caused by improper handling of HTTP cache control directives. The middleware does not respect standard cache control headers such as Cache-Control: private or Cache-Control: no-store, which may result in private or authenticated responses being cached and subsequently exposed to unauthorized users.

Details

The vulnerability exists in the cache decision logic of Cache Middleware. When determining whether a response should be cached, the middleware does not take HTTP cache control semantics into account and may cache responses that are explicitly marked as private by the application. While some runtimes, such as Cloudflare Workers, enforce cache control restrictions at the platform level, other runtimes including Deno, Bun, and Node.js rely on the middleware’s behavior. As a result, applications running on these runtimes may unintentionally cache sensitive responses.

Impact

This issue can lead to Web Cache Deception and information disclosure. If an authenticated user accesses an endpoint that returns user-specific or sensitive data and the response is cached despite being marked as private, subsequent unauthenticated requests may receive the cached response. This may result in the exposure of personally identifiable information or session-related data. The impact is limited to applications that use the hono/cache middleware and rely on it to correctly honor HTTP cache control directives.

Affected Components

Cache Middleware

1 / 2
Source: GitHub
First published (updated )
Severity
6.5
EPSS
0.01%
AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N

Summary

IP Restriction Middleware in Hono is vulnerable to an IP address validation bypass. The IPV4REGEX pattern and convertIPv4ToBinary function in src/utils/ipaddr.ts do not properly validate that IPv4 octet values are within the valid range of 0-255, allowing attackers to craft malformed IP addresses that bypass IP-based access controls.

Details

The vulnerability exists in two components:

1. Permissive regex pattern: The IPV4REGEX (/^[0-9]{0,3}\.[0-9]{0,3}\.[0-9]{0,3}\.[0-9]{0,3}$/) accepts octet values greater than 255 (e.g., 999). 2. Unsafe binary conversion: The convertIPv4ToBinary function does not validate octet ranges before performing bitwise operations. When an octet exceeds 255, it overflows into adjacent octets during the bit-shift calculation.

For example, the IP address 1.2.2.355 is accepted and converts to the same binary value as 1.2.3.99:

355 = 256 + 99 = 0x163 After bit-shifting: (1 << 24) + (2 << 16) + (2 << 8) + 355 = 0x01020363 = 1.2.3.99

Impact

An attacker can bypass IP-based restrictions by crafting malformed IP addresses:

Blocklist bypass: If 1.2.3.0/24 is blocked, an attacker can use 1.2.2.355 (or similar) to bypass the restriction. Allowlist bypass: Requests from unauthorized IP ranges may be incorrectly permitted.

This is exploitable when the application relies on client-provided IP addresses (e.g., X-Forwarded-For header) for access control decisions.

Affected Components

IP Restriction Middleware src/utils/ipaddr.ts: IPV4REGEX, convertIPv4ToBinary, distinctRemoteAddr

1 / 2
Source: GitHub
First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203