high · 7.5CVE-2026-63490Sep 2, 2026

CVE-2026-63490: handlebars-springmvc Arbitrary File Read via URL Fragment Suffix Bypass

Shubham Kandhare
Security Engagement Manager, SecureLayer7

A Spring MVC application using Handlebars as its view engine can be tricked into reading any file on the server just by adding a '#' character to a user-controlled view name, bypassing the only…

Packagecom.github.jknack:handlebars-springmvc
Ecosystemmaven
Affected< 4.5.3
Fixed in4.5.3
CVE-2026-63490: handlebars-springmvc Arbitrary File Read via URL Fragment Suffix Bypass

The problem

SpringTemplateLoader resolves view names through Spring's ResourceLoader without any path-containment check. Every other loader in the project was hardened by commit d177cdee, but SpringTemplateLoader was missed.

The sole protection against malicious file: or classpath: view names is the .hbs suffix appended by AbstractTemplateLoader.resolve(). A '#' character at the end of the view name pushes .hbs into the URL fragment. Both Spring's FileUrlResource and the JDK's URL.openStream() silently discard the fragment, so the file actually opened is the bare attacker-supplied path.

No authentication is required.

Proof of concept

A working proof-of-concept for CVE-2026-63490 in com.github.jknack:handlebars-springmvc, with the exact payload below.

http
GET /view?name=file:/etc/passwd%23 HTTP/1.1
Host: target.example.com

AbstractTemplateLoader.resolve() does string concatenation: prefix + normalize(uri) + suffix. When the uri ends with '#', the result is 'file:/etc/passwd#.hbs'. Both java.net.URI.getSchemeSpecificPart() (used by Spring's FileUrlResource.exists()) and java.net.URL.getFile() (used by URL.openStream()) strip the fragment before accessing the file system, so the path opened is '/etc/passwd' not '/etc/passwd.hbs'.

The patch (commit 61f43423) adds a validateNoUnsafeUrlComponents check that throws IllegalArgumentException if the resolved URL carries a non-null ref (fragment) or query, closing the bypass. CWE-36 / CWE-22.

The fix

Upgrade com.github.jknack:handlebars-springmvc to 4.5.3. The fix validates the resolved URL and rejects any URL containing a fragment (#) or query string before the resource is opened. As a short-term workaround, reject view names that contain ':', '#', or '..' at the controller or view-resolver layer before they reach HandlebarsViewResolver.

Reporter not attributed.

References: [1][2][3][4][5]

Related research