CVE-2026-19872 Overview
CVE-2026-19872 is a stored and reflected cross-site scripting (XSS) vulnerability in the Perl module HTML::FormHandler at versions before 0.410000. The library's built-in wrappers and renderers interpolate form error messages directly into HTML output without escaping. When a submitted value fails validation against a check regexp, check_list, or type constraint, the raw input is spliced into the resulting error string and rendered inside an error span. An attacker who submits HTML markup to an affected field triggers script execution in the victim's origin. Re-rendering a rejected value later produces the stored variant of the attack.
Critical Impact
Any application using HTML::FormHandler rendering roles with field-level validation returns attacker-controlled markup live in error output, enabling session theft, credential capture, and account takeover in the victim's browser context.
Affected Products
- HTML::FormHandler for Perl, all versions prior to 0.410000
- Applications relying on the library's built-in rendering roles for error output
- Forms with fields declared using check regexp, check_list, or type constraints (default configuration)
Discovery Timeline
- 2026-09-08 - CVE-2026-19872 published to NVD and disclosed on the Openwall oss-security mailing list
- 2026-09-10 - Last updated in NVD database
Technical Details for CVE-2026-19872
Vulnerability Analysis
The flaw is a classic output-encoding failure [CWE-79]. HTML::FormHandler builds error messages by interpolating the rejected user-submitted value into a template string, then hands the completed string to add_error via _apply_actions. When the field is later rendered, the wrappers and renderers emit the error span with the message inlined directly into HTML. No HTML entity encoding is applied.
Two library-defined messages, no_match and not_allowed, splice the submitted value into their output. Failing type constraints likewise embed the rejected value in the resulting message. Because the vulnerable path is reached through default field declarations without custom validators, most consuming applications inherit the issue implicitly.
Applications that render errors through their own escaping template layer, rather than the library's rendering roles, are not affected. Only the Select field previously escaped its output, and it did so only at render time.
Root Cause
The library treats error message strings as pre-formatted HTML fragments rather than untrusted data. The Select field imported HTML::Entities to escape option values, but the shared error-message path did not. As a result, values that failed regexp checks, list membership, or type coercion were preserved verbatim and reinjected into the DOM through the rendering roles.
Attack Vector
An attacker submits a form value containing HTML markup, such as a <script> payload, to any field guarded by a check regexp, check_list, or type constraint. Validation fails, the library builds the corresponding no_match, not_allowed, or type-constraint message with the raw value included, and the rendered response returns the payload inside the error span. If the rejected value is persisted and re-displayed on subsequent requests, the same payload becomes stored XSS. Exploitation requires user interaction to load the response but no authentication.
// Patch excerpt from Changes file
- Fix exception when field 'result' has been garbage-collected
- Crypt::* and MIME::Base64 prereqs added in last release are moved to
optional prereqs
+ - Fix CVE-2026-19872
+ by html escaping all error message on render
+ only the Select field did this previously but when adding the error message to the field
+ instead of only when rendering to HTML
0.40068 Thu Jul 20, 2017
Add RequestToken field
Source: GitHub Commit Patch
Detection Methods for CVE-2026-19872
Indicators of Compromise
- HTTP responses containing form error spans with unescaped <, >, or <script characters originating from user input
- Requests that submit HTML or JavaScript payloads to fields backed by regexp, list, or type-constraint validation
- Persisted form values in application storage containing script tags or event-handler attributes that later reappear in rendered error output
Detection Strategies
- Inventory Perl applications and their dependencies to identify HTML::FormHandler releases earlier than 0.410000 via cpanfile, META.json, or installed distribution manifests
- Add web application firewall rules that flag form submissions containing raw HTML tags targeting endpoints known to render HTML::FormHandler errors
- Perform dynamic testing that submits benign XSS canaries such as <x-cve></x-cve> to validated fields and inspects the rendered error span for the literal markup
Monitoring Recommendations
- Log validation failure events at the application layer with the raw submitted value hash so analysts can correlate payload attempts across sessions
- Alert on outbound Content Security Policy (CSP) violation reports referencing inline script execution in pages that render form errors
- Track anomalous browser-side errors and requests to attacker-controlled domains originating from authenticated user sessions on form-heavy endpoints
How to Mitigate CVE-2026-19872
Immediate Actions Required
- Upgrade HTML::FormHandler to version 0.410000 or later across all Perl application environments
- Audit form definitions for fields using check, check_list, or type constraints and confirm the render path uses the patched library
- Deploy or tighten a Content Security Policy that blocks inline script execution to reduce impact if unpatched code paths remain
Patch Information
The fix is delivered in HTML::FormHandler 0.410000, published via MetaCPAN HTML::FormHandler Changes. The upstream commit is available as a GitHub Commit Patch. The patch applies HTML entity escaping to all error messages at render time and removes the Select-only escaping in favor of a uniform escape path. Additional context is available on the Openwall OSS-Security Mailing List.
Workarounds
- Replace the library's default rendering roles with an application-controlled template layer that HTML-escapes all error message output
- Override the no_match and not_allowed messages, and any type-constraint messages, to omit the submitted value from the rendered string
- Sanitize or reject form input containing HTML metacharacters before it reaches HTML::FormHandler validation for fields that will be re-rendered
# Upgrade HTML::FormHandler using cpanm
cpanm HTML::FormHandler@0.410000
# Verify installed version
perl -MHTML::FormHandler -e 'print $HTML::FormHandler::VERSION, "\n"'
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

