Vulnerability Information
| Item | Details |
|---|---|
| Vulnerability Name | PHPEMS Points Concurrent Usage Race Condition Vulnerability |
| Affected Versions | PHPEMS 11.0 and earlier |
| Type | Logic Flaw |
| Severity | Medium |
Reproduction Environment
- Test Site: Local deployment
- Source Code Setup: Download any version from the official website: https://www.phpems.net/
- Tool: Burp Suite
Reproduction Steps
-
Prepare data: Obtain a valid PHPEMS user account that has sufficient points for purchasing courses.
-
Create a points-consuming course: Set up a course in the system that requires points to access/purchase (configure the course to deduct points upon successful purchase).
-
Capture the course purchase request: Use Burp Suite to intercept the HTTP request generated when clicking the “Purchase Course” button with the prepared account. This request is the core endpoint for points consumption.

-
Conduct concurrent testing: Import the captured request into Burp Suite Turbo Intruder, load a race condition script, and send multiple concurrent requests simultaneously.

-
Verify the result: Check the system backend and user account— the same points-consuming course is successfully purchased more than 10 times, while the user’s points are not deducted proportionally (or only partially deducted).
Verification Result : A single coupon can be used to recharge all accounts.Only one coupon redemption record is logged in the backend system.
Impact
- Attackers can maliciously obtain unauthorized access to paid courses or virtual assets by exploiting the mismatch between points deduction and transaction records.
- If the platform’s points are convertible to real currency or require monetary payment to acquire, the vulnerability may result in direct economic losses for the platform.
- Compromises the fairness of the platform’s virtual asset system and undermines user trust.
Mitigation Recommendations
- Implement database row-level locking (e.g., MySQL FOR UPDATE clause) for points consumption operations to ensure that concurrent requests are processed serially and avoid race conditions.
- Add real-time validation of points balance and consumption status before executing each points-deducting transaction. Reject the request immediately if the remaining points are insufficient.
- Introduce a transaction log mechanism: Record each points consumption event with a unique transaction ID, and verify the consistency between transaction records and points balance after concurrent operations.
- Restrict the frequency of concurrent requests for points-consuming actions (e.g., limit the number of course purchase requests per account within a specific time window) to prevent abuse.