Blog
From the Shadows: The Authentication That Went Missing
·
Friday, August 29, 2025

Brad Geesaman
Principal Security Engineer
From the Shadows: The Authentication That Went Missing
What if an endpoint meant for internal use only quietly exposed file upload privileges to the entire internet? No keys. No tokens. No rate limiting.
It looked harmless enough. A simple POST endpoint that returns a pre-signed S3 URL to upload a file. Nothing fancy. But when you look closer, something important is missing: authentication.
That’s all it takes. One unguarded endpoint, and suddenly, anyone who finds it can start uploading to your bucket.
What the Feature Was Supposed to Do
The original intent was straightforward: allow users to upload files to an S3 bucket via a pre-signed URL, obtained by calling a backend endpoint that generates it securely. Authentication was intended so that only known, logged-in users should be able to request upload URLs.
But somewhere between development and deployment, the authentication check got disabled. Maybe for local testing. Maybe for internal tooling. Either way, it stayed that way. And the endpoint quietly went live, unauthenticated.
Shining a Light on this Flaw
This is an anonymized version of a real finding detected by the Ghost platform in a Python/Flask application.
See if you can spot the problem.
Did you catch it? The critical piece missing here is a decorator like @requires_auth
. That one line would enforce authentication on all calls to this endpoint. It’s subtle, and it’s easy for the eye to miss.
How would this be Exploited?
Now, there’s nothing stopping an unauthenticated caller from generating pre-signed URLs at will:
And just like that, they receive:
Which provides them with a short-lived URL they can use to directly upload files to that S3 bucket. They can upload malicious files to change or disrupt a workflow. But perhaps more costly would be a Denial of Wallet attack where they repeatedly upload a huge quantity of large files and leave you with a surprise cloud bill at the end of the month.
The Fix
Fixing this requires explicitly adding an authentication check to the route. That means wrapping the function with a decorator (e.g. @requires_auth
) that verifies credentials before allowing the request to proceed:
Now, unauthenticated requests will receive a 401 response instead of a pre-signed upload token.
Why This Hides from Legacy Scanners
Static analysis tools often look for common and specific patterns to surface potential risks with keywords like exec
, eval
, or direct access to sensitive resources. They might even check for authentication decorators, but they won’t always have the context to know when those have a real impact when detected.
Dynamic scanners won’t fare much better unless they:
Know the expected authentication model,
Are aware this endpoint exists (e.g. it’s not documented in an OpenAPI spec), and
Understand that S3 pre-signed URLs are a sensitive output worth flagging.
The endpoint isn’t doing anything obviously dangerous. It’s not deleting data or returning secrets. But it grants a capability like an upload token to a cloud resource which only makes sense in a trusted context. Without that context, scanners typically move on.
This is a classic example of something that looked ok in isolation, but becomes risky once you understand how it’s meant to be used. Ghost's Agentic AI scanning engine understands the context—and flags this kind of exposure immediately.
Takeaways for Developers
Never assume authentication exists just because it used to.
For sensitive operations involving uploads, downloads, or modifications to cloud resources: enforce access control explicitly.
Always test endpoints from the outside-in, like an attacker would. If you find yourself saying “this should be protected,” stop and confirm that it actually is.
Stay tuned for the next edition of From the Shadows, where we’ll shine a light on another subtle flaw lurking just beneath the surface of everyday application logic.
If you’d like to see how Ghost uncovers these kinds of issues before attackers do, sign up here.