Skip to content

CSRF enables bounce rule deletion in phpList <= 3.6.16 #1116

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 bounce rule by tricking an authenticated administrator into loading a
specially crafted URL, for example embedded in an image tag on an external page.

Affected files: public_html/lists/admin/bouncerules.php, bouncerule.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:L/A:L (5.4 Medium)
CWE-352

The deletion is performed by a GET request (?page=bouncerules&del=N) with no CSRF token check.
phpList's central CSRF check (verifyCsrfGetToken) uses enforce=false, meaning it only validates
the token when a "tk" parameter is actually present. Since a cross-origin image load does not
include the "tk" parameter, the check is skipped entirely.

I confirmed this by:

  1. Creating a bounce rule in phpList 3.6.15 (Docker install).
  2. Sending the GET deletion request with the admin session but without the "tk" parameter.
  3. Confirming the rule was deleted from phplist_bounceregex.

The fix is to call verifyCsrfGetToken() with enforcement (default enforce=1) in both
bouncerules.php and bouncerule.php before processing the "del" parameter, or to convert
deletions to POST-only actions protected by verifyToken().

This is similar to how bouncerule.php already handles its GET-based delete at line 15 but
without any token check.

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