From 2628464f659c39fafbc32147d569553eb07d41d7 Mon Sep 17 00:00:00 2001
From: Zoran Ilibasic <zilibasic@s7designcreative.com>
Date: Tue, 3 Mar 2020 11:24:51 +0100
Subject: [PATCH] Improved token handling in the LostPassword requests.

---
 CHANGES.md                             |  1 +
 Kernel/System/Web/InterfaceAgent.pm    | 19 +++++++++++++++++++
 Kernel/System/Web/InterfaceCustomer.pm | 19 +++++++++++++++++++
 3 files changed, 39 insertions(+)

--- a/Kernel/System/Web/InterfaceAgent.pm
+++ b/Kernel/System/Web/InterfaceAgent.pm
@@ -620,6 +620,25 @@ sub Run {
 
         # get user login by token
         if ( !$User && $Token ) {
+
+            # Prevent extracting password reset token character-by-character via wildcard injection
+            # The wild card characters "%" and "_" could be used to match arbitrary character.
+            if ( $Token !~ m{\A (?: [a-zA-Z] | \d )+ \z}xms ) {
+
+                # Security: pretend that password reset instructions were actually sent to
+                #   make sure that users cannot find out valid usernames by
+                #   just trying and checking the result message.
+                $LayoutObject->Print(
+                    Output => \$LayoutObject->Login(
+                        Title       => 'Login',
+                        Message     => Translatable('Sent password reset instructions. Please check your email.'),
+                        MessageType => 'Success',
+                        %Param,
+                    ),
+                );
+                return;
+            }
+
             my %UserList = $UserObject->SearchPreferences(
                 Key   => 'UserToken',
                 Value => $Token,
--- a/Kernel/System/Web/InterfaceCustomer.pm
+++ b/Kernel/System/Web/InterfaceCustomer.pm
@@ -561,6 +561,25 @@ sub Run {
 
         # get user login by token
         if ( !$User && $Token ) {
+
+            # Prevent extracting password reset token character-by-character via wildcard injection
+            # The wild card characters "%" and "_" could be used to match arbitrary character.
+            if ( $Token !~ m{\A (?: [a-zA-Z] | \d )+ \z}xms ) {
+
+                # Security: pretend that password reset instructions were actually sent to
+                #   make sure that users cannot find out valid usernames by
+                #   just trying and checking the result message.
+                $LayoutObject->Print(
+                    Output => \$LayoutObject->Login(
+                        Title       => 'Login',
+                        Message     => Translatable('Sent password reset instructions. Please check your email.'),
+                        MessageType => 'Success',
+                        %Param,
+                    ),
+                );
+                return;
+            }
+
             my %UserList = $UserObject->SearchPreferences(
                 Key   => 'UserToken',
                 Value => $Token,
