CVE-2026-93709 Overview
CVE-2026-93709 is an information disclosure vulnerability in the Perl web framework Dancer2 before version 2.2.0. The AutoPage handler compares the incoming request path against the layout directory name as text, while the subsequent file lookup canonicalises it. Attackers can bypass the guard using a doubled slash, a dot segment, a percent-encoded slash, or a different capitalisation on case-insensitive filesystems. The handler then serves a layout template as a page, disclosing other layouts stored in the application's layout directory. The handler is disabled by default and only exposed when auto_page is enabled. This issue is classified under [CWE-41: Improper Resolution of Path Equivalence].
Critical Impact
Remote unauthenticated attackers can read Dancer2 layout templates by requesting equivalent-spelling paths that bypass the AutoPage guard.
Affected Products
- Dancer2 for Perl, versions prior to 2.2.0
- Applications with the auto_page configuration option enabled
- Deployments on case-insensitive filesystems are additionally exposed to capitalisation-based bypasses
Discovery Timeline
- 2026-09-22 - CVE-2026-93709 published to the National Vulnerability Database
- 2026-09-22 - Issue discussed on the OpenWall oss-security mailing list
- 2026-09-23 - Last updated in NVD database
Technical Details for CVE-2026-93709
Vulnerability Analysis
Dancer2's AutoPage handler automatically resolves incoming request paths to template files under the views directory. To prevent layout templates from being served as pages, the handler compares the request path against the layout directory name using textual string comparison. The template lookup that follows canonicalises the path on disk, which introduces an equivalence gap between the guard and the resolver.
An attacker crafts a request whose path is textually distinct from the layout directory name but resolves to the same location after canonicalisation. Because the guard rejects only the literal spelling, the handler proceeds and renders a layout template as a standalone page. The layout wrapping every page is already public content, so disclosure is limited to sibling layout templates in the same directory.
Root Cause
The root cause is inconsistent path handling between security enforcement and file resolution. The guard performs a textual comparison of user input against a directory name, while Path::Tiny and template lookup logic later normalise the path. Any equivalent spelling that survives the guard reaches the resolver intact.
Attack Vector
Exploitation requires only network access to an application that has enabled auto_page. Attackers request paths using bypass variants such as //layouts/main, /./layouts/main, /layouts%2Fmain, or /Layouts/main on case-insensitive filesystems. No authentication or user interaction is required.
# Patch context: lib/Dancer2/Handler/AutoPage.pm
use Moo;
use Carp 'croak';
use Dancer2::Core::Types;
+use Path::Tiny ();
with qw<
Dancer2::Core::Role::Handler
Source: GitHub Commit Patch (293fce0)
The follow-up commit replaces the textual guard with a filesystem-identity check, mirroring the containment approach used by send_file at Dancer2/Core/App.pm:1180-1182 via $dir->realpath->subsumes($file_path):
- # Authoritative check: is the page's own directory, resolved on
- # disk, inside the layout directory? Decided from what is actually
- # there rather than the request path's spelling, the same
- # containment approach send_file uses at
- # Dancer2/Core/App.pm:1180-1182
- # ($dir->realpath->subsumes($file_path)).
+ # Authoritative check: is the page's own directory the layout
+ # directory, or inside it? Decided from what is actually on disk
+ # rather than from the request path's spelling.
Source: GitHub Commit Patch (753b385)
Detection Methods for CVE-2026-93709
Indicators of Compromise
- Web server access logs containing request paths with doubled slashes (//), dot segments (/./), or percent-encoded separators (%2F) targeting URLs beneath the application's views hierarchy
- Requests using varied capitalisation of directory names such as layouts, Layouts, or LAYOUTS returning HTTP 200 responses
- Unusual 200 responses for paths that resemble template filenames rather than legitimate application routes
Detection Strategies
- Inspect Dancer2 application logs for AutoPage handler activity resolving to files inside the layout directory
- Instrument reverse proxies or WAF rules to flag path normalisation anomalies before requests reach the Perl application
- Compare the Dancer2 dependency version reported by cpanm --info Dancer2 or Module::CoreList against 2.2.0 across deployed hosts
Monitoring Recommendations
- Alert on repeated requests from a single source containing percent-encoded slashes or dot segments
- Track HTTP responses that return content resembling layout wrappers (for example, containing <!DOCTYPE html> scaffolding without body content) from non-standard URLs
- Aggregate template rendering events in a centralised log store and correlate them with configuration changes to auto_page
How to Mitigate CVE-2026-93709
Immediate Actions Required
- Upgrade Dancer2 to version 2.2.0 or later on all Perl application servers
- Audit application configuration for auto_page: 1 and disable it where the feature is not required
- Review layout templates for any embedded secrets, internal endpoints, or debug markup that should not be publicly disclosed
Patch Information
The fix is included in Dancer2 2.2.0, published on MetaCPAN. Two commits address the issue: 293fce0 introduces Path::Tiny for canonical path resolution, and 753b385 replaces the textual guard with a filesystem-identity containment check. See the MetaCPAN Dancer2 Changes and GitHub Issue #1823 for release details.
Workarounds
- Set auto_page: 0 in the Dancer2 configuration to disable the vulnerable handler entirely
- Place a reverse proxy in front of the application that normalises request paths before forwarding, rejecting doubled slashes, dot segments, and percent-encoded separators
- Restrict filesystem permissions on the layout directory so that sensitive template fragments are not colocated with the application's public layout wrapper
# Configuration example: disable AutoPage in config.yml
auto_page: 0
# Or upgrade Dancer2 using cpanm
cpanm Dancer2@2.2.0
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

