dgxcode

Unauthenticated Account Deletion via IDOR on a Live Venue Platform

How a missing authentication check on a critical account endpoint allowed any anonymous caller to permanently delete fan accounts by guessing or harvesting their membership GUID, confirmed across five byte-exact replications.

The target

A mature public bug bounty program covers multiple event venues, ticketing platforms, and festival domains. While the primary ticketing flow is protected by layered anti-bot challenges and browser fingerprinting, the regional venue subsidiaries often run on shared white-label membership platforms.

One of these regional venue platforms exposes an account management interface for fans to view purchases, manage preferences, and request account deletion.

The discovery

During endpoint enumeration of the platform's client-side bundles, an asynchronous handler for account lifecycle operations was mapped:

DELETE /api/account/delete HTTP/1.1
Host: <venue-platform>.test
Content-Type: application/json

{"MembershipGuid":"<target-guid>"}

In standard operation, the frontend attaches session cookies and an anti-forgery token when a logged-in user requests deletion through their profile settings.

However, inspecting the controller logic revealed an asymmetric validation order: the handler parses the request body and executes the deletion query before verifying that an authenticated session exists or that the caller owns the specified membership identifier.

The reproduction

To confirm the vulnerability without interfering with third-party data, two independent test accounts were created in a clean environment:

  1. Victim Account: Registered with a designated test email. The application assigned a unique MembershipGuid. Login was verified: HTTP 200 with an active session.
  2. Control Test: A DELETE request with a randomly generated, non-existent GUID was submitted without credentials. The server responded with HTTP 404 Not Found, proving the endpoint performs real record lookups rather than returning a generic success response.
  3. The Unauthenticated Attack: The same DELETE request was sent containing the victim account's GUID, with zero cookies and no Authorization header:
DELETE /api/account/delete HTTP/1.1
Host: <venue-platform>.test
User-Agent: Mozilla/5.0
Content-Type: application/json

{"MembershipGuid":"b6c4a1e9-4e2f-4a8b-9d3c-1a2b3c4d5e6f"}

The server immediately answered:

HTTP/1.1 204 No Content
  1. State Mutation Verification: Subsequent authentication attempts with the victim's credentials failed with HTTP 400 Bad Request ("Account does not exist"). The victim's original email address was immediately eligible for re-registration, returning HTTP 200 OK on a fresh signup flow. This confirmed the account had been completely purged from the backend database.

Impact & blast radius

The weakness combines CWE-306 (Missing Authentication for Critical Function) and CWE-639 (Authorization Bypass Through User-Controlled Key):

  • Zero-barrier exploitation: No account, API key, or credential is required.
  • Permanent denial of service: Fans lose their booking history, loyalty tiers, and stored payment profiles.
  • Shared platform exposure: Inspecting HTTP response headers (X-Backend-Name) revealed that the exact same backend signature powers at least three other in-scope venue websites within the program.

Remediation

The application must enforce strict authentication and ownership checks before evaluating any resource key:

// Vulnerable pattern
[HttpDelete("delete")]
public IActionResult Delete([FromBody] DeleteRequest req) {
    var user = _db.Users.Find(req.MembershipGuid);
    if (user == null) return NotFound();
    _db.Users.Remove(user);
    _db.SaveChanges();
    return NoContent();
}

// Secure pattern
[Authorize]
[HttpDelete("delete")]
public IActionResult Delete() {
    var currentGuid = User.FindFirst("MembershipGuid")?.Value;
    if (string.IsNullOrEmpty(currentGuid)) return Unauthorized();
    var user = _db.Users.Find(currentGuid);
    _db.Users.Remove(user);
    _db.SaveChanges();
    return NoContent();
}

The finding was submitted to the program with full reproduction logs and remediations.