CVE-2026-93710: Dancer2 versions from 2.0.0 before 2.2.0 for Perl dispatch a route that a dying hook refused when the exception handler halts the response in compile_hooks
Dancer2 versions from 2.0.0 before 2.2.0 for Perl dispatch a route that a dying hook refused when the exception handler halts the response in compilehooks.
A hook that dies fires core.app.hookexception, then calls cleanup unless the failing hook is the exception handler. A handler that halts does not stop that cleanup, which discards the request, response and session the dispatcher has yet to read, so the refused route runs.
The handler has to halt the response object by calling its halt method or setting ishalted: the halt keyword unwinds through withreturn before cleanup runs.
A check in a before hook is not enforced: the caller gets the refusal, while the route body runs and its writes land.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
Dancer2to a version that resolves this vulnerability.Fixed in 2.2.0
Event History
Frequently Asked Questions
Which deployments are realistically exposed?
Deployments using Dancer2 from 2.0.0 before 2.2.0 are affected when a hook can die and the core.app.hook_exception handler halts the response object. The impact is especially relevant where a before hook is used to refuse access to a route.
What conditions are required for a refused route to run?
A hook must die, triggering core.app.hook_exception, and that exception handler must halt by calling the response object's halt method or by setting is_halted. Cleanup then discards request, response, and session state before the dispatcher reads them, allowing the refused route to execute.
Does a before-hook access check reliably prevent route execution?
No. Under the affected conditions, the caller receives the refusal but the route body still runs, and its writes can be applied. A before hook is therefore not enforced as a route-execution barrier in this scenario.
What can be changed if upgrading is not immediately possible?
Avoid halting the response object from the hook exception handler by calling its halt method or setting is_halted. The halt keyword instead unwinds through with_return before cleanup runs.
How can I identify whether an application is affected in practice?
Check whether it uses an affected Dancer2 version and registers a core.app.hook_exception handler. Review whether that handler halts the response object after a hook failure, particularly when failing before hooks are used to deny access to routes.