[00.00_r1gor]
[00.00_bugbounty]
r1gor

all write-ups

A Semicolon Got Me 530 Endpoints on a Car Manufacturer

Target is the digital manual platform of one of the biggest car manufacturers in the world. Serves vehicle docs in 45 languages, connects to the in-car infotainment system. Runs Spring Boot.

Standard recon. Check for /v3/api-docs. Connection reset. WAF doing its job. So I added ;.js to the path.

# blocked
curl -sk "https://[TARGET]/v3/api-docs"
# Status: 000, Size: 0

# not blocked
curl -sk "https://[TARGET]/v3/api-docs;.js"
# Status: 200, Size: 496362

Half a megabyte of OpenAPI spec. 530 endpoints. The WAF looked at the extension and saw a .js file. Spring Boot stripped the semicolon (matrix parameter per RFC 3986) and served the docs. Same thing worked on all 5 hosts including production.

what was inside

Credentials in URL paths:

GET /api/moapi/V9/authenticate/auth/{userName}/{password}

Every login attempt logged in plaintext in access logs, proxy logs, browser history. I hit the endpoint on production, no auth needed. Returns [] for bad creds instead of an error.

Dev endpoints sitting in production:

POST /api/dev/consumer/token/create
GET  /api/dev/consumer/token/decode

Token create + decode = forged auth.

Internal service token endpoints:

GET /api/vw-services/V1/idk/access-token
GET /api/vw-services/V1/gvf/auth-token

Destructive admin operations:

POST /api/data/V2/clear          -- wipes all data
DELETE /api/users/V1/user/{name} -- deletes users

In-car infotainment management:

GET /api/mibtokenless/V1/queryRemoteReset
GET /api/mibtokenless/V1/downloadPackages/{f}/{token}

The word "tokenless" in that path tells you everything.

why it works

The WAF and Spring Boot parse URLs differently. WAF sees /v3/api-docs;.js as a JS file request. Spring sees /v3/api-docs with a matrix param. Two parsers, two interpretations, one gap.

Fix is to enable StrictHttpFirewall in Spring Security (rejects semicolons), or just turn off API docs in production.

This bypass is well documented. It keeps working because WAF rules match what the WAF sees, not what the app sees.