Bug#1147105: trixie-pu: package libhtml-formhandler-perl/0.40068-3~deb13u1
Salvatore Bonaccorso
carnil at debian.org
Mon Sep 7 21:01:30 BST 2026
Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: libhtml-formhandler-perl at packages.debian.org, team at security.debian.org, debian-perl at lists.debian.org, gregoa at debian.org, carnil at debian.org
Control: affects -1 + src:libhtml-formhandler-perl
User: release.debian.org at packages.debian.org
Usertags: pu
Hi SRM'ers
This is out of scope for 13.7 now, but please consider it for 13.8.
libhtml-formhandler-perl in trixie is vulenerable to CVE-2022-4993,
allowing an attacker selected method dispatch and resource exhaustion.
We did mark it as no-dsa, but would be nice to have it fixed in trixie
as well.
The unstable upload on purpose back in august did only apply the patch
for the CVE, so trixie's upload will be a rebuild of the unstable
version to trixie.
Attached the debdiff for the upload.
QA testing has as well been performed on reverse dependencies as per
https://debusine.debian.net/debian/developers/work-request/1232972/
Regards,
Salvatore
-------------- next part --------------
diff -Nru libhtml-formhandler-perl-0.40068/debian/changelog libhtml-formhandler-perl-0.40068/debian/changelog
--- libhtml-formhandler-perl-0.40068/debian/changelog 2022-03-25 16:32:07.000000000 +0000
+++ libhtml-formhandler-perl-0.40068/debian/changelog 2026-09-05 14:25:23.000000000 +0000
@@ -1,3 +1,17 @@
+libhtml-formhandler-perl (0.40068-3~deb13u1) trixie; urgency=medium
+
+ * Rebuild for trixie
+
+ -- Salvatore Bonaccorso <carnil at debian.org> Sat, 05 Sep 2026 16:25:23 +0200
+
+libhtml-formhandler-perl (0.40068-3) unstable; urgency=medium
+
+ * Team upload.
+ * HTML::FormHandler: stop routing foreign text into the Locale::Maketext
+ format (CVE-2022-4993)
+
+ -- Salvatore Bonaccorso <carnil at debian.org> Fri, 14 Aug 2026 06:00:11 +0200
+
libhtml-formhandler-perl (0.40068-2) unstable; urgency=medium
[ Damyan Ivanov ]
diff -Nru libhtml-formhandler-perl-0.40068/debian/patches/CVE-2022-4993-r2.patch libhtml-formhandler-perl-0.40068/debian/patches/CVE-2022-4993-r2.patch
--- libhtml-formhandler-perl-0.40068/debian/patches/CVE-2022-4993-r2.patch 1970-01-01 00:00:00.000000000 +0000
+++ libhtml-formhandler-perl-0.40068/debian/patches/CVE-2022-4993-r2.patch 2026-09-05 14:25:23.000000000 +0000
@@ -0,0 +1,210 @@
+From: CPANSec Security Scanner Bot <cpan-security at security.metacpan.org>
+Subject: [PATCH] HTML::FormHandler: stop routing foreign text into the Locale::Maketext format
+
+The first argument to add_error is the Locale::Maketext FORMAT: bracket groups
+in it are compiled into method-dispatch code. Three kinds of text that
+FormHandler did not author reach that position, all of them carrying submitted
+request data:
+
+ * _apply_actions traps warnings into $error_message (Validate.pm, the
+ $SIG{__WARN__} handler). A warning survives a SUCCESSFUL action, so an
+ ordinary numeric transform on a text field turns
+ `Argument "[sprintf,%2000000000d,0]" isn't numeric` into the format --
+ Perl quotes the value verbatim, so the group is well formed and reaches
+ CORE::sprintf with an attacker-chosen width (~GB allocation).
+ * a type constraint's failure message. Moose renders the rejected value with
+ Devel::PartialDump when it can load it, Type::Tiny always uses its own
+ dumper, and both render a reference in bracket-and-comma form -- so on any
+ field with `apply => [ Str ]`, two same-named request parameters put
+ `[ "a", "b" ]` in the format and maketext croaks, which add_error re-dies:
+ an unhandled 500 with no payload at all.
+ * exceptions from a coercion or transform.
+ * a date parser's error message. Field/Date.pm passes
+ `$strp->errmsg || $@` -- DateTime::Format::Strptime's own text -- straight
+ into the format position. DTFS 1.80 answers a rejected value with the
+ fixed string "Your datetime does not match your pattern.", so there is no
+ reachable payload through it today; that is a property of the current
+ version of a separate distribution rather than of this code, and the
+ `|| $@` fallback is a second channel that was not exercised. Escaped for
+ the same reason as the others.
+
+Escape the bracket-notation metacharacters in all four before they are used
+as a format. Tilde is Locale::Maketext's escape, and text with no brackets is
+returned unchanged, so lexicon lookups and translated type-constraint messages
+are byte-identical to before.
+
+Also: add_error derefs an arrayref first argument into (template, @args). That
+spelling is the same list-or-arrayref convenience idiom as add_element_class
+and friends; it is not documented for add_error, and an instrumented run of the
+distribution's own suite (150 files, 1491 tests) never reaches the branch. What
+does reach it is request data -- `$field->add_error($field->value)` where the
+request parser folded a duplicate parameter into an arrayref puts submitted
+text in element 0. Since no message the library raises arrives in that shape,
+treat an arrayref argument as a value: keep the deref, render element 0
+literally. A caller who wants a compiled template passes it as a plain list,
+`$field->add_error($template, @args)`, which is the documented spelling and is
+unchanged.
+
+One case cannot be fixed here: an application that concatenates the value into
+its own message, `add_error("The value '" . $field->value . "' is not
+allowed")`, is indistinguishable from a legitimate template, so the add_error
+POD now documents the hazard and the inert-argument idiom.
+
+Behaviour trade-offs -- the only output changes outside the attack cases:
+
+ * a custom type constraint whose own message block uses bracket notation
+ (message { 'Try [quant,1,thing]' }) now renders that literally. Such a
+ block receives the rejected value and can interpolate it, so escaping it
+ is the safe default; a maintainer who would rather keep those compiled can
+ exempt the has_message branch specifically.
+ * an application calling the undocumented arrayref spelling with a template
+ that uses bracket notation, add_error([ 'Try [quant,_1,thing]', 3 ]), now
+ renders it literally; the list spelling of the same call still compiles.
+
+FormHandler's own message templates, and application templates passed to
+add_error together with their arguments, are unaffected.
+
+Verified against the 0.40068 test suite: 150 files, 1491 tests, PASS both
+before and after. A before/after table of rendered error messages
+(maxlength, minlength, required, invalid select value, integer range,
+duplicate-parameter arrays, application template with arguments, plain and
+bracketed type messages, plain and bracketed warnings and exceptions) is
+byte-identical except the lines above.
+
+--- a/lib/HTML/FormHandler/Validate.pm
++++ b/lib/HTML/FormHandler/Validate.pm
+@@ -158,13 +158,40 @@
+ $self->add_action(@apply_list);
+ }
+
++# Locale::Maketext treats its FORMAT argument as bracket-notation source: any
++# '[...]' group inside it is compiled into method-dispatch code (see _compile
++# in Locale::Maketext). Messages FormHandler itself authors are templates on
++# purpose, but three kinds of text reaching _apply_actions are not ours and do
++# embed request data:
++#
++# * warnings trapped by the $SIG{__WARN__} handler in _apply_actions -- Perl
++# quotes the offending value into them verbatim, so a submitted value like
++# '[sprintf,%2000000000d,0]' arrives as a well-formed bracket group;
++# * a type constraint's failure message -- the type system renders a rejected
++# reference in bracket-and-comma form (Devel::PartialDump when Moose can
++# load it, Type::Tiny's own dumper always), so a duplicate request
++# parameter is enough to put '[ "a", "b" ]' into the format;
++# * exceptions from a coercion or a transform.
++#
++# Render those literally instead. Tilde is Locale::Maketext's escape character;
++# text containing no brackets comes back unchanged, so lexicon lookups and
++# translated type-constraint messages behave exactly as before.
++sub _escape_bracket_notation {
++ my ( $self, $text ) = @_;
++
++ return $text if !defined $text || ref $text;
++ $text =~ s/~/~~/g;
++ $text =~ s/([\[\]])/~$1/g;
++ return $text;
++}
++
+ sub _apply_actions {
+ my $self = shift;
+
+ my $error_message;
+ local $SIG{__WARN__} = sub {
+ my $error = shift;
+- $error_message = $error;
++ $error_message = $self->_escape_bracket_notation($error);
+ return 1;
+ };
+
+@@ -199,10 +226,11 @@
+ eval { $new_value = $tobj->coerce($value) };
+ if ($@) {
+ if ( $tobj->has_message ) {
+- $error_message = $tobj->message->($value);
++ $error_message = $self->_escape_bracket_notation(
++ $tobj->message->($value) );
+ }
+ else {
+- $error_message = $@;
++ $error_message = $self->_escape_bracket_notation($@);
+ }
+ }
+ else {
+@@ -210,7 +238,8 @@
+ }
+
+ }
+- $error_message ||= $tobj->validate($new_value);
++ $error_message ||= $self->_escape_bracket_notation(
++ $tobj->validate($new_value) );
+ }
+ # now maybe: http://search.cpan.org/~rgarcia/perl-5.10.0/pod/perlsyn.pod#Smart_matching_in_detail
+ # actions in a hashref
+@@ -235,7 +264,8 @@
+ $action->{transform}->($value, $self);
+ };
+ if ($@) {
+- $error_message = $@ || $self->get_message('error_occurred');
++ $error_message = $self->_escape_bracket_notation($@)
++ || $self->get_message('error_occurred');
+ }
+ else {
+ $self->_set_value($new_value);
+--- a/lib/HTML/FormHandler/Field.pm
++++ b/lib/HTML/FormHandler/Field.pm
+@@ -864,7 +864,21 @@
+ unless ( defined $message[0] ) {
+ @message = ( $class_messages->{field_invalid});
+ }
+- @message = @{$message[0]} if ref $message[0] eq 'ARRAY';
++ if ( ref $message[0] eq 'ARRAY' ) {
++ # An arrayref argument is a value, not a message specification. The
++ # list-or-arrayref spelling here is the same convenience idiom as
++ # add_element_class and friends, it is not documented for add_error,
++ # and nothing in the distribution reaches it -- but request data does:
++ # $field->add_error($field->value), where the request parser folded a
++ # duplicate parameter into an arrayref, puts submitted text in element
++ # 0, which _localize hands to Locale::Maketext as bracket-notation
++ # source. Dereference as before, but render element 0 literally.
++ # A caller who really wants a compiled template passes it as a plain
++ # list: $field->add_error($template, @args).
++ my @args = @{ $message[0] };
++ $args[0] = $self->_escape_bracket_notation( $args[0] );
++ @message = @args;
++ }
+ my $out;
+ try {
+ $out = $self->_localize(@message);
+@@ -1198,6 +1212,18 @@
+
+ return $field->add_error( 'bad data' ) if $bad;
+
++The first argument is the localization FORMAT, which for a
++L<Locale::Maketext> handle means bracket notation in it is compiled and
++executed. Do not build that argument out of submitted data: a value
++containing a C<[...]> group would be run as a method call rather than
++shown. Pass the value as an argument instead, where it is inert:
++
++ # wrong -- the submitted value becomes part of the format
++ $field->add_error( "The value '" . $field->value . "' is not allowed" );
++
++ # right -- the format is yours, the value is just an argument
++ $field->add_error( "The value '[_1]' is not allowed", $field->value );
++
+ =item error_fields
+
+ Compound fields will have an array of errors from the subfields.
+--- a/lib/HTML/FormHandler/Field/Date.pm
++++ b/lib/HTML/FormHandler/Field/Date.pm
+@@ -66,7 +66,11 @@
+
+ my $dt = eval { $strp->parse_datetime( $self->value ) };
+ unless ($dt) {
+- $self->add_error( $strp->errmsg || $@ );
++ # The parser's message is not ours to hand to the localizer as a
++ # bracket-notation FORMAT. DateTime::Format::Strptime 1.80 does not
++ # quote the rejected input into errmsg, but that is the parser's text
++ # to change, and the `|| $@` fallback is a second channel.
++ $self->add_error( $self->_escape_bracket_notation( $strp->errmsg || $@ ) );
+ return;
+ }
+ $self->_set_value($dt);
diff -Nru libhtml-formhandler-perl-0.40068/debian/patches/series libhtml-formhandler-perl-0.40068/debian/patches/series
--- libhtml-formhandler-perl-0.40068/debian/patches/series 2022-03-25 16:32:07.000000000 +0000
+++ libhtml-formhandler-perl-0.40068/debian/patches/series 2026-09-05 14:25:23.000000000 +0000
@@ -1,2 +1,3 @@
whatis.patch
whatis-Field-Role-RequestToken.patch
+CVE-2022-4993-r2.patch
More information about the pkg-perl-maintainers
mailing list