In March 2026, I conducted a penetration test against a social media-style web application (referred to as TargetApp.io). The engagement was authorized by the platform’s owner and spanned approximately two weeks. The most critical vulnerability was discovered on the second day. While the test began as a traditional black-box assessment, simulating an external attacker with no insider knowledge, it evolved into what industry practitioners classify as a credentialed black box or grey box assessment.
This distinction is important. During the engagement, I discovered a publicly exposed API key embedded in client-side code. While the key itself was intended to be public (a anon key), its existence allowed me to perform authenticated queries against the backend database. In effect, I was operating with partial knowledge; a non-public asset (the key) was leveraged to conduct unauthenticated queries that should have been restricted. This shaped the depth of testing and ultimately led to the discovery of a critical database misconfiguration.
This article provides a comprehensive walkthrough of the engagement, including methodology, detailed findings, the credentialed factor’s role in testing, and key takeaways for developers and security practitioners.
Engagement Overview
Scope and Objectives
The test targeted the primary domain (targetapp.io) and its associated subdomains. The engagement was conducted as a black-box assessment with a credentialed/grey box twist: I had no prior access to source code, architecture documentation, or privileged credentials, but I did obtain a publicly exposed API key that enabled backend queries. This placed the test in a unique category.

In this case, The anon Key was discovered during standard reconnaissance (visible in browser network traffic). While it was intended to be public, its misuse potential transformed the assessment from purely unauthenticated testing to a scenario where I could perform credentialed queries against the backend, without ever holding a user account.
Methodology
I followed a structured methodology aligned with industry-standard frameworks, including:
- OWASP Testing Guide — for web application vulnerability classification
- PTES (Penetration Testing Execution Standard) — for structured phases and reporting
The engagement was divided into the following phases:
- Reconnaissance
- Architecture Analysis
- Authentication & Authorization Testing
- API Security Testing
- Database Security Assessment
- Client-Side Security Testing
- Business Logic Testing
The Credentialed Factor: Why It Matters
In traditional black-box testing, the tester has no credentials and operates entirely as an unauthenticated user. However, modern web applications often expose non-public assets, API keys, backend references, and internal endpoints through client-side code. An attacker with basic reconnaissance skills can extract these assets and use them to probe deeper into the application’s infrastructure.
This test began as a standard black-box engagement. During reconnaissance, I observed that the application made direct client-side requests to a backend database provider. Embedded in these requests was a public anon key, a credential intended to allow unauthenticated client applications to interact with the database under controlled conditions. While the key itself is meant to be public, its presence allowed me to perform queries that should have been restricted by proper Row Level Security (RLS) policies.
With this key, I effectively transitioned from an unauthenticated external attacker to a credentialed user with partial backend access. This is the essence of a credentialed black box or grey box test: operating with partial knowledge that an attacker could realistically obtain, then using that knowledge to uncover deeper vulnerabilities.
This approach ultimately revealed the most critical finding of the engagement: RLS was disabled on multiple tables, meaning The anon Key provided unrestricted read and write access to the entire user database.
Detailed Findings
A total of seven findings were identified during this engagement, ranging from Informational to Critical severity. The credentialed factor played a direct role in uncovering F-01, the most severe finding.
F-01: Database RLS Disabled — Unauthenticated PII Access (CRITICAL)
Severity — Critical
CVSS Score 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
Affected Componentsprofiles, follows, watchlists tables in the backend database
Discovery Method: Credentialed/grey box – leveraging public anon key discovered during reconnaissance
Description
The application uses a Backend-as-a-Service (BaaS) provider for its database and authentication layer. During standard reconnaissance, I observed that the application made direct client-side requests to the backend provider. Embedded in these requests were:
- The full backend project reference URL
- The public anon API key
- API endpoint structures
With this information, specifically the anon Key, I began probing the backend API directly. What I discovered was that Row Level Security (RLS) was completely disabled on at least three critical tables: profiles, follows, and watchlists. RLS is a security feature that restricts which rows a user can access based on SQL policies. When disabled, any request containing the public anon key can perform unrestricted read and write operations on these tables.
Because I now possessed the anon key (a credential, although a public one), I was operating in a credentialed capacity, even though I had never created a user account or authenticated in the traditional sense. This partial knowledge allowed me to move beyond surface-level testing and directly query the backend database.
Technical Evidence
Using only the public anon Key extracted from browser network traffic, I executed the following unauthenticated requests:
Read All User Profiles:
GET /rest/v1/profiles?select=*
Host: [redacted].supabase.co
apikey: [public anon key]
Response: Full user records returned, including:
- User IDs, usernames, display names, bios, avatar URLs, and countries
- Stripe customer IDs and subscription IDs
- Subscription tier, status, renewal dates
- Admin privilege flags
- Account creation dates and activity metrics
- Theme preferences and personalization settings
Write to Any User Profile:
PATCH /rest/v1/profiles?id=eq.[target_user_id]
Host: [redacted].supabase.co
apikey: [public anon key]
Content-Type: application/json
{"display_name": "hijacked"}
Response: 204 No Content – modification successful


Data Exposed
1.1 Data Category: Personally Identifiable Information (PII)
Examples: Personally Identifiable Information (PII): Usernames, bios, location, avatar URLs
Risk: Privacy violation, user profiling
1.2 Data Category: Payment & Billing,
Examples: Stripe customer IDs, subscription details, Revenue Cat IDs,
Risk: Financial fraud, targeted support scams
1.3 Data Category: Privilege Data
Examples: Admin flags
Risk: Identification of high-value targets
1.4 Data Category: Social Graph
Examples: Follower/following relationships
Risk: Mapping user networks
1.5 Data Category: Private Content
Examples: Watchlist entries marked as private
Risk: Exposure of non-public preferences

Impact Analysis
This finding represents a complete breach of confidentiality and integrity. Approximately under 20 users were registered on the platform at the time of testing, all of whom had their data exposed. An unauthenticated attacker who discovers the anon key (as I did) could:
- Harvest all user PII for identity theft or social engineering
- Identify paying customers and admin accounts for targeted attacks
- Modify any user’s profile information, potentially defacing profiles or disrupting accounts
- Map complete social graphs and private user behavior
The credentialed factor was critical to this discovery. Without the anon Key, I would have been limited to testing the application’s public-facing interface. With it, operating in a grey box capacity, I was able to directly probe the backend and uncover the complete lack of access controls.
Remediation Steps
- Immediate: Enable RLS on all tables in the Supabase dashboard.
- Immediate: Create RLS policies that restrict SELECT operations to authenticated users, viewing only their own records.
- Immediate: Revoke write permissions from the public anon key; ensure the key is scoped to the minimum required permissions.
- Audit all remaining tables for the same misconfiguration, and assume all tables are exposed until verified.
- Review backend logs to determine if unauthorized access occurred prior to this finding being reported.
- Consider rotating the anon key, noting that this will require updating all client-side references.
- Engage legal counsel to assess breach notification obligations.
F-02: Open Redirect — Multiple Unvalidated Parameters (MEDIUM)
Severity Medium
CVSS Score 6.1 (AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N)
Affected Endpoints: Multiple login and callback endpoints
Discovery Method: Traditional black-box testing
Status Open — Remediation required
Description
The application contains unvalidated redirect parameters on multiple endpoints. Six distinct redirect parameters were confirmed to be vulnerable: next, goto, redirect_uri, callback, continue, and url. None of these parameters validates that the destination URL belongs to the application’s domain before performing the redirect. The breadth of affected parameters indicates that redirect validation is absent at the framework or middleware level—this is not an isolated bug in a single code path.
Proof of Concept
Each of the following parameters successfully redirected to an external domain (https://evil.com):
https://targetapp.io/login?next=https://evil.com
https://targetapp.io/auth/callback?goto=https://evil.com
https://targetapp.io/oauth/confirm?redirect_uri=https://evil.com
https://targetapp.io/verify?callback=https://evil.com
https://targetapp.io/account/link?continue=https://evil.com
https://targetapp.io/share?url=https://evil.com
Attack Scenario
A realistic attack chain exploiting this vulnerability, now made more dangerous by the information obtained through credentialed testing:
- Attacker discovers backend infrastructure (as I did via F-03) during reconnaissance.
- Attacker registers a lookalike domain (e.g., targetapp-account.com) and hosts a convincing fake login page that mirrors the exposed backend structure.
- Attacker crafts a phishing email containing the malicious URL:
https://targetapp.io/login?next=https://targetapp-account.com/steal - The victim sees a legitimate targetapp.io URL in the link and trusts it.
- Victim logs in successfully on the real login page.
- The victim is silently redirected to the attacker’s site, which now appears authentic because it leverages knowledge of the exposed backend.
Impact Analysis
Medium severity. The vulnerability enables phishing attacks that are significantly more convincing than standard phishing because the initial URL is a legitimate domain. When combined with the backend exposure discovered during credentialed testing, an attacker can create a highly convincing fake environment that mirrors the real application’s infrastructure.

Remediation Steps
- Implement an allowlist of permitted redirect destinations. Only allow relative paths or explicitly approved same-origin URLs.
- Reject or sanitize any redirect parameter that contains an absolute URL with an external domain.
- Default to a safe location (e.g., homepage) when an invalid redirect target is detected.
- Add automated tests that verify external URLs in redirect parameters result in safe fallbacks rather than open redirects.
F-03: No Rate Limiting on Account Registration (MEDIUM)
Severity Medium
CVSS Score 5.3 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L)
Affected EndpointPOST /auth/sign-up
Discovery Method: Traditional black-box testing
StatusOpen – Remediation required
Description
The account registration endpoint does not implement rate limiting. During testing, ten concurrent registration requests using distinct email addresses and usernames all returned HTTP 200 OK responses with no throttling, CAPTCHA challenge, or blocking response. An attacker can automate mass account creation with no restrictions.
Technical Evidence
A script was used to submit ten registration requests in rapid succession:
for i in {1..10}; do
curl -X POST https://targetapp.io/auth/sign-up
-H "Content-Type: application/json"
-d "{"email":"[email protected]","password":"Password123!"}" &
done
wait
Result: All ten requests returned 200 OK. No 429 Too Many Requests Responses were observed.

Attack Scenarios
- Spam & Abuse Attacker creates thousands of accounts to post spam, fake reviews, or abusive content.
2. Sybil Attack: Mass account creation to manipulate voting, ratings, or social trust metrics.
3. Ban Evasion: Banned users can instantly re-register with a new email address.
4. Resource Exhaustion: Mass registrations fill the user database, potentially incurring unexpected costs.
Remediation Steps
- Implement rate limiting on POST /auth/sign-up (e.g., 5 registrations per IP per hour).
- Add CAPTCHA to the registration flow to prevent automated submissions.
- Enforce email verification before new accounts can access sensitive features.
- Monitor registration patterns for anomalies indicating automated abuse.
F-04: Backend Provider Reference Exposed Client-Side (LOW)
Severity Low
Category: Information Disclosure
Affected Component Client-side JavaScript / Network traffic
Discovery Method: Traditional black-box reconnaissance
Role in Credentialed Testing: This exposure provided the anon key and backend reference that enabled credentialed probing
Description
The application makes direct client-side requests to its BaaS backend, exposing the full project reference URL in browser network traffic during normal usage. This reveals:
- The backend provider and technology stack
- The specific project identifier
- API endpoint structure and internal column names
- The public anon API key – the credential that enabled further testing
Evidence
Observed in browser Developer Tools Network tab:
GET /rest/v1/profiles?select=theme_preference,subscription_tier&id=eq.[redacted]
Host: [redacted].supabase.co
Authorization: Bearer [redacted]
apiKey: [redacted] <--The credential that enabled grey box testing
Impact Analysis
Low severity individually, but critical in context. This finding alone does not directly expose sensitive data. However, it provided the partial knowledge (the anon key) that allowed me to transition from an unauthenticated black-box test to a credentialed grey box assessment. Without this exposure, the critical RLS misconfiguration (F-01) might not have been discovered.
Remediation Steps
- Route API calls server-side through a proxy or API routes to abstract the backend provider and project reference from client-side traffic.
- Audit RLS policies on all exposed tables to ensure proper access controls.
- Consider using a custom domain for the backend project to obscure the project reference ID.
- Ensure the public anon Key is scoped to the minimum required permissions, and RLS policies enforce those permissions.
F-05: Missing HTTP Security Headers (LOW)
Severity Low
Category Security Misconfiguration
Discovery Method: Traditional black-box testing
Description
The application does not return standard HTTP security headers in its responses, including:
- Content-Security-Policy
- X-Frame-Options
- X-Content-Type-Options
- Strict-Transport-Security
Impact Analysis
No direct exploitation is possible from missing headers alone. However, their absence removes browser-enforced mitigations that would reduce the impact of other vulnerabilities.
Remediation Steps
Add the following headers to all responses:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
F-06 & F-07: Unused Subdomains and DNS Records (INFORMATIONAL)
Severity Informational
Affected Assets: Multiple subdomains pointing to cloud infrastructure
Discovery Method: DNS enumeration (reconnaissance phase)
Description
During DNS enumeration, multiple subdomains were found with valid DNS A records pointing to cloud infrastructure IPs but with no active deployment attached. Subdomain takeover was confirmed not possible due to A records rather than CNAME delegation.
Affected Subdomains
- api.targetapp.io
- blog.targetapp.io
- account.targetapp.io
Remediation Steps
Remove DNS A records for unused subdomains or deploy placeholder pages if reserved for future use. Conduct periodic DNS audits.
Lessons Learned: The Credentialed Factor in Practice
For Developers
- Treat all client-side credentials as compromised. The anon key may be “public” by design, but if RLS is disabled, it becomes a skeleton key to your database. Always enforce RLS policies regardless of key scope.
- Never assume client-side exposure is harmless. The exposure of backend references and API keys in client-side code provided the partial knowledge that escalated this test from black box to credentialed grey box. An attacker will do the same.
- Defense in depth applies to credentials. Even if a key is meant to be public, layer additional controls: RLS, rate limiting, IP restrictions, and server-side proxying.
- Redirect validation must be systemic. Open redirects are not isolated bugs; they often indicate a lack of validation at the framework level. Implement centralized redirect validation.
For Security Practitioners
- Embrace the credentialed factor. When you discover a credential during reconnaissance, use it. Operating with partial knowledge, even when that credential is “public”, can reveal vulnerabilities that pure black-box testing might miss.
- Document the shift in test methodology. Clearly articulate when a test evolves from black box to grey box. This transparency helps clients understand how findings were discovered and why they are credible
- Combine findings for greater impact. The backend exposure (F-03) enabled the RLS misconfiguration discovery (F-01). Open redirects (F-04) become more dangerous when an attacker can build a convincing fake environment using exposed backend details.
For Organizations
- Understand the risk of client-side exposure. Modern applications routinely embed API keys, endpoints, and internal references in client-side code. These are not secrets, they are assets that must be secured with proper backend controls.
- Conduct regular security assessments with varying methodologies. A purely black-box test might not probe backend APIs with discovered credentials. Consider credentialed and grey box testing to simulate realistic attacker behavior.
- Prioritize critical findings immediately. The RLS misconfiguration was reported verbally before the final written report. Accelerated communication is essential for urgent issues.
What I’d Do Differently Next Time?
If I ran this test again, I’d automate backend API fuzzing as soon as I found the anon key; I spent too long manually probing. Also, I’d check for RLS misconfigurations before testing business logic, since that yielded the highest impact finding.
Conclusion
This penetration test began as a standard black-box engagement but evolved into a credentialed black box / grey box assessment when a public anon key, exposed client-side, was leveraged to probe backend systems. That partial knowledge led to the discovery of a critical failure in access control: Row Level Security was disabled on multiple database tables, granting unrestricted read and write access to the entire user database.
The credentialed factor was essential to this discovery. Without the key, I would have remained an unauthenticated external attacker, limited to testing the application’s public interface. With it, I could directly query the backend and uncover a vulnerability that exposed every user’s PII, payment details, and private content.
This engagement underscores several key principles:
- Client-side exposure is not harmless; it provides the partial knowledge that enables deeper testing and real-world attacks.
- Credentials, even “public” ones, must be paired with proper access controls; RLS is non-negotiable for database security.
- Defense in depth matters; security headers, rate limiting, and redirect validation add layers that reduce the impact of other vulnerabilities.
- Methodology matters; clearly documenting when a test transitions from black box to grey box provides transparency and helps clients understand the realistic attacker perspective.
All findings were delivered with actionable remediation steps. The most critical issue was reported verbally before the final written report to accelerate remediation. Following these recommendations will significantly improve the security posture of the application and protect its users from data exposure, phishing attacks, and automated abuse.
This article is based on an actual penetration test and is shared for educational and portfolio purposes. All identifying information has been redacted to maintain confidentiality.
How a Public Anon Key Led to Full Database Compromise was originally published in OSINT Team on Medium, where people are continuing the conversation by highlighting and responding to this story.