Blog

From the Shadows: A Shortcut to Full Account Takeover

0 Mins Read

·

Friday, September 5, 2025

Brad Geesaman

Principal Security Engineer

Self-registration is supposed to make life easier for users. Enter a few details, confirm your identity, and set up access. But sometimes, the check that’s meant to protect identity does little more than glance at it, and that’s when things go wrong.

In this case, a utility billing platform implemented a flawed validation step during account creation. The logic behind it reduced identity verification to a formality. As a result, an attacker could impersonate any customer, register on their behalf, and take full control of their account. No email. No consent. No password reset.

What the Flow Was Intended to Do

To prevent unauthorized registrations, the app required users to submit identifying details such as first name, last name, user ID, date of birth, and postal code before continuing with signup.

Sounds reasonable at first, but the backend logic came up short. It only checked the first letter of the first and last name. And when combined with a guessable ID format and a ZIP code, an attacker had everything they needed.

Where the Logic Failed

This anonymized example was surfaced by Ghost’s account lifecycle agent, which identifies weaknesses in registration, reset, and recovery flows.

Here’s a simplified version of the vulnerable code in C#:


[HttpPost("api/validate")]
public IActionResult ValidateUser([FromBody] ValidationRequest req)
{
    var record = _db.Users
        .Where(u => u.Id == req.Id
                    && u.PostalCode == req.PostalCode
                    && u.FirstName.StartsWith(req.FirstName.Substring(0, 1))
                    && u.LastName.StartsWith(req.LastName.Substring(0, 1)))
        .FirstOrDefault();

    if (record == null)
        return Unauthorized();

    return Ok(new { token = GenerateRegistrationToken(record.Id


At first glance, the logic might seem harmless. But it completely fails to confirm the user’s actual identity. If someone submits common initials such as “J” for the first name and “S” for the last name, and those letters match the account record, the validation succeeds.

What This Allows: Total Account Takeover

The attack path here is short and silent:

  1. Use a script to iterate over likely customer IDs.

  2. Pair them with ZIP codes (public and guessable).

  3. For each combination, submit initials for first and last name.

  4. When validation returns a token, proceed to register the account.

  5. Set a new password and gain full access.

This isn’t partial exposure or limited access. The attacker ends up logged in as the real customer with the ability to view billing data, update information, even cut service or reroute notifications. And the legitimate user receives no warning that anything happened.

It’s a full account takeover. Zero clicks. No interaction from the victim.

What the Code Should Have Done

The fix here isn’t complicated. Validation should check exact values for identity fields—not shortcuts:


[HttpPost("api/validate")]
public IActionResult ValidateUser([FromBody] ValidationRequest req)
{
    var record = _db.Users
        .Where(u => u.Id == req.Id
                    && u.PostalCode == req.PostalCode
                    && u.FirstName.Equals(req.FirstName, StringComparison.OrdinalIgnoreCase)
                    && u.LastName.Equals(req.LastName, StringComparison.OrdinalIgnoreCase)
                    && u.DateOfBirth == req.DateOfBirth)
        .FirstOrDefault();

    if (record == null)
        return Unauthorized();

    return Ok(new { token = GenerateRegistrationToken(record.Id


Now, validation requires the user to know several precise details which makes impersonation significantly harder and brute-forcing practically infeasible with request rate-limiting in place.

Why Tools Miss This

Traditional scanners look for structural flaws such as missing access control, dangerous input handling, and misconfigurations. This wasn’t any of those. There were no unsafe calls. No direct data exposure. Just logic that gave the illusion of validation without enforcing it.

Ghost caught it because it understands what the flow is trying to protect. If identity is being verified, our models check whether the validation actually provides meaningful protection. When it doesn't, we raise the alarm.

Ghost doesn’t just scan code. It understands the intention behind it—and flags violations when logic undermines trust.

Developer Takeaways


  • Partial matches are rarely sufficient for identity validation. If your goal is to confirm user identity before granting access, rely on high-entropy fields and complete matches. Initials and shared demographic fields like ZIP codes introduce massive overlap across users and shouldn’t be used in isolation.

  • Design validation logic with an attacker’s mindset. It’s not enough for a flow to "usually" reject bad input. Ask: what is the minimal amount of information required to impersonate someone? Could it be guessed or scraped?

  • Identity checks deserve the same scrutiny as authentication. Flows like self-registration, account recovery, and email confirmation often bypass formal auth—but their impact is equivalent. They’re part of the perimeter.

More flaws like this are hiding in everyday logic. We’ll keep pulling them into the light.

Want to see how Ghost detects silent risks in account flows before they go live? Get started here.

Step Into The Underworld Of
Autonomous AppSec

Step Into The Underworld Of
Autonomous AppSec

Step Into The Underworld Of
Autonomous AppSec

Ghost Security provides autonomous app security with Agentic AI, enabling teams to discover, test, and mitigate risks in real time across complex digital environments.

Join our E-mail list

Join the Ghost Security email list—where we haunt vulnerabilities and banish breaches!

© 2025 Ghost Security. All rights reserved

Ghost Security provides autonomous app security with Agentic AI, enabling teams to discover, test, and mitigate risks in real time across complex digital environments.

Join our E-mail list

Join the Ghost Security email list—where we haunt vulnerabilities and banish breaches!

© 2025 Ghost Security. All rights reserved

Ghost Security provides autonomous app security with Agentic AI, enabling teams to discover, test, and mitigate risks in real time across complex digital environments.

Join our E-mail list

Join the Ghost Security email list—where we haunt vulnerabilities and banish breaches!

© 2025 Ghost Security. All rights reserved