Skip to content

CSRF enables admin account deletion in phpList <= 3.6.16 #1117

Description

@geo-chen

reported via email on 3 June 2026 - no response:

I am reporting a Cross-Site Request Forgery vulnerability in phpList 3.6.16 and earlier. An
attacker can delete any non-self administrator account by tricking a logged-in super-administrator
into loading a specially crafted URL, such as one embedded as an image in an email.

Affected file: public_html/lists/admin/admins.php
Affected versions: all versions through 3.6.16
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H (8.1 High)
CWE-352

The admins.php page deletes administrators via a GET request (?page=admins&delete=N) without
verifying a CSRF token. phpList's central CSRF check (verifyCsrfGetToken in index.php) uses
enforce=false, which means it only validates the "tk" token when the parameter is actually
present in the request. Cross-origin GET requests omit the "tk" parameter, so the check is
bypassed.

I confirmed this vulnerability by:

  1. Inserting a test administrator (id=2) into a fresh phpList 3.6.15 Docker installation.
  2. Sending the GET deletion request with the super-admin session cookie but without the "tk"
    parameter.
  3. Confirming the administrator was removed from phplist_admin (only id=1 remained).

The response contained "Deleting .. Done", confirming successful deletion.

The fix is to call verifyCsrfGetToken() with enforcement (enforce=1, the default) in admins.php
before processing the "delete" parameter, consistent with how admin.php protects its POST handler
with verifyToken().

I am also reporting two additional related CSRF issues in the same codebase:

  • massremove.php: POST handler for bulk subscriber deletion/blacklisting, no CSRF token
  • bouncerules.php: GET handler for bounce rule deletion, no CSRF token

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions