October 19, 2026
6,820 Subdomains And One 403 That Broke Me
A single 403 on an internal-looking path kept me for weeks. The control was enforced by source address at the proxy, and no request was…

By Nitin yadav
4 min read
A single 403 on an internal-looking path kept me for weeks. The control was enforced by source address at the proxy, and no request was ever going to beat it.
Hello, I am Nitin.
I enumerated 6,820 subdomains on a single public bug bounty programme.
I want you to sit with that number for a second, because when I first saw it I felt something that I now recognise as a trap. It felt like wealth. Six thousand eight hundred doors. Surely, statistically, one of them is unlocked.
What followed was several weeks of the most disciplined work I have done, one genuinely promising lead, and a conclusion I did not want.
What 6,820 subdomains actually is
It is not six thousand targets. This is the first thing nobody tells you.
A large organisation's subdomain space is mostly sediment. Marketing campaign hosts from 2016. Regional variants of the same application. Wildcard DNS entries that resolve for anything you type. Content delivery and cloud infrastructure that is not the organisation's asset at all. Internal naming conventions pointing at private addresses. Staging environments that were decommissioned but never removed from DNS.
So the first real work is not finding more. It is reduction.
Resolve them and discard what does not. Probe for live services and discard what does not respond. Group by response fingerprint, because four hundred hosts returning an identical page are one target, not four hundred. Screenshot at scale and look at the grid, because your eye will find the three interesting things faster than any script. Check what is in scope, because a significant portion of any large enumeration belongs to third parties and testing those is not bug hunting, it is unauthorised access.
By the time I finished that funnel, the real list was a single text file of active leads. Not thousands. A shortlist I could hold in my head.
That file is the actual output of recon. The 6,820 was raw material.
The one that looked like money
One host had an internal-sounding path that returned 403 Forbidden.
If you hunt, you know the feeling. A 404 is nothing. A 200 is public. A 403 is somebody telling you that a thing exists, is there, is working, and is not for you. It is the single most seductive response code in web security.
I went at it properly and I went at it for a long time.
I tried every path normalisation trick I knew, because access control rules and the application behind them do not always agree about what a path means. I tried header-based approaches, since some access rules trust forwarding headers to determine who is asking. I tried method variation, because rules written for one HTTP verb sometimes do not cover others. I looked for alternative routes to the same application through other hosts, different ports, and any non-production variant of the environment. I read everything public I could find about how that infrastructure is typically deployed, looking for a documented default that might have survived into production.
I kept notes the whole time. Every attempt, every response, timestamped.
Why it was never going to work
The block was enforced at the reverse proxy layer, by source address.
That is not a rule that can be tricked by a clever request, because the decision is made before the request reaches anything that could interpret it cleverly. The proxy compares where the connection came from against an allowlist and terminates the conversation. No amount of path manipulation, header injection or verb substitution changes the source address of a TCP connection.
There was no bug. There was a correctly configured control doing exactly what it was designed to do, and I had spent a meaningful part of my month proving it worked.
The skill I actually learned
Here is the thing I was not expecting: recognising that was the valuable part.
Every hunter has a 403 in their history that they could not let go of. Hours accumulate. And the longer you spend, the harder it becomes to walk away, because walking away means the time was wasted, and so you spend more time to avoid admitting you spent time. That is the mechanism, and it is not a security problem, it is a human one.
What I use now is a simple discipline. Before I go deep on any lead, I write down what I am testing, and what result would tell me it is a dead end. For this one, the honest answer was "if the block is enforced by source address at the proxy, stop." I could have determined that far earlier than I did, and I did not want to, because determining it would have ended the excitement.
I also keep a lead file with a status against each entry now. Open, exhausted, out of scope, or revisit. An exhausted lead gets written up in two lines explaining what I tried and why it is closed. That write-up is what stops me from returning to it three weeks later and repeating the same month.
What it was worth
No bounty. But that programme is part of why I have responsible disclosure acknowledgements from a number of organisations, and the recon methodology I built during it is the one I still use on every engagement, including paid client work where the same funnel saves days.
The volume was not the value. The funnel was the value.
And there is a strategic point hidden in all of this. If you enumerate 6,820 subdomains on a mature programme, so has everyone else. Public programmes with large attack surfaces are the most heavily automated targets on the internet, and the shallow findings are gone within hours of appearing. Depth beats breadth, because breadth is what everybody else's scanner already did.
Conclusion — steal this checklist
- Recon output is a shortlist, not a subdomain count. Reduction is the work; enumeration is the raw material.
- Funnel properly: resolve, probe, cluster by response fingerprint, screenshot at scale, and confirm scope before touching anything.
- Verify ownership and scope carefully. A large portion of any enumeration belongs to third parties, and testing those is not authorised.
- Before going deep on a lead, write down what result would make you stop. Decide the exit condition while you are still objective.
- Understand where a control is enforced. A block at the proxy by source address cannot be defeated by request-level cleverness.
- Keep a lead file with statuses and two-line closure notes, so an exhausted lead stays exhausted.
- Assume shallow findings on large public programmes are already taken. Depth is the only edge you have.
- Count methodology as a return. A hunt that pays nothing but leaves you with a reusable funnel was not a loss.