Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,111 @@ Help Token: ARD_zUaNgNilGTg9oYUnMhfa3foMvL7qspRpBJ-YZog8RLbTjCTBolt_WjQQ3myTaOqu
reason: AUTH_PERMISSION_DENIED
```

### Brute Force API endspoints
### Discovery-document driven API recon

Once you have a valid key, don't just test the obvious public APIs. In Google environments, **discovery documents** can work as a machine-readable attack-surface map exposing **resources, methods, paths, HTTP verbs, parameters, and request/response schemas**.

Useful targets:

```bash
# Public / common path
curl -s 'https://serviceusage.googleapis.com/$discovery/rest?key=<api-key>'

# Hidden docs behind a visibility label
curl -s 'https://serviceusage.googleapis.com/$discovery/rest?labels=GOOGLE_INTERNAL&key=<api-key>'
```

Notes:

- Compare the document size and method count with and without labels such as `GOOGLE_INTERNAL`.
- A **true nonexistent method** usually returns an **HTML 404**. A **JSON 404** with `Method not found.` can indicate that the method exists but the **API key project is missing a required visibility label**.
- Some first-party APIs are easier to reach via `*.clients6.google.com` or undocumented `*-pa.googleapis.com` hosts than via the public API explorer.

This is specially useful to enumerate **internal/admin APIs accidentally exposed to the Internet** and to build custom fuzzers from the schema instead of guessing JSON fields manually.

### Key ownership filtering at scale

If you collect many Google API keys from APKs, browser traffic, IPAs or binaries, you may want to quickly identify **which project owns each key** and whether it belongs to the target company.

A practical trick is to intentionally call an API that is **not enabled** for the key. Google frequently leaks the backing **project number** in the error:

```bash
curl -s 'https://protos.googleapis.com/$discovery/rest?key=<api-key>'
```

Look for messages like:

```text
Protos API has not been used in project 244648151629 before or it is disabled
```

That project number can then be correlated with other endpoints, leaked metadata, or internal company-mapping logic to separate **in-scope first-party keys** from customer / third-party projects.

### Handle key restrictions before discarding a key

A restricted key is not necessarily useless. Preserve the context where the key was found and replay requests with the matching headers:

```bash
# Browser restricted
curl -H 'X-Goog-Api-Key: <api-key>' \
-H 'Referer: https://target.google.com' \
'https://servicemanagement.googleapis.com/v1/operations'

# iOS restricted
curl -H 'X-Goog-Api-Key: <api-key>' \
-H 'X-Ios-Bundle-Identifier: com.google.GoogleMobile' \
'https://servicemanagement.clients6.google.com/v1/operations'

# Android restricted
curl -H 'X-Goog-Api-Key: <api-key>' \
-H 'X-Android-Package: com.google.android.settings.intelligence' \
-H 'X-Android-Cert: <sha1-signing-cert>' \
'https://servicemanagement.clients6.google.com/v1/operations'
```

Common restriction classes:

- **HTTP Referer**
- **iOS bundle ID** (`X-Ios-Bundle-Identifier`)
- **Android package + signing cert** (`X-Android-Package` + `X-Android-Cert`)
- **Server IP** restrictions, which generally cannot be bypassed remotely

### First-party auth / origin whitelist hints

Some Google web APIs accept a mix of **session cookie + first-party authorization headers** and are hosted on `*.clients6.google.com`. When testing these APIs:

- Keep `Origin` and `Referer` compatible with the product that normally uses the API.
- A `401` with `reason: SESSION_COOKIE_INVALID` can actually mean the **origin is not whitelisted**, not that the cookie is bad.
- Publicly reachable APIs that only accept internal origins such as `*.corp.google.com` are high-value candidates for broken access control review.

### Brute force enabled APIs and fuzz documented methods

As you might not know which APIs are enabled in the project, it would be interesting to run the tool [https://github.com/ozguralp/gmapsapiscanner](https://github.com/ozguralp/gmapsapiscanner) and check **what you can access with the API key.**

After you identify reachable services, prefer **schema-driven fuzzing** over blind guessing:

- Generate requests directly from discovery docs
- Replay the same request with **all known working keys**
- Normalize errors so you can distinguish **invalid input** from **visibility-label / auth / restriction** failures
- For numeric object identifiers, try nearby values such as `ID-1`, `ID+1`, `1`, `2`, `100`, `1000`
- Only report when you confirm **cross-user data access** or another real authorization failure; plain enumeration is usually not enough by itself

### Common vuln pattern: unauthenticated direct-object reference

A recurring bug pattern is an **internal/admin API** that accepts a victim-controlled identifier (for example `gaiaId`) and only validates that the request carries a usable API key, but **never checks whether the caller is authorized to access that specific object**.

```bash
curl 'https://gfibervoice-pa.googleapis.com/v1/BssGetVoiceSettings?gaiaId=<victim_gaia_id>' \
-H 'X-Goog-Api-Key: <api-key>'
```

If the endpoint returns another user's phone number, email address, settings, or other private fields, treat it as a classic **IDOR / broken access control** issue.

## References

- [Hacking Google with AI: AI-Assisted Discovery-Document Fuzzing of Google APIs](https://brutecat.com/articles/hacking-google-with-ai)
- [Google APIs Explorer](https://developers.google.com/apis-explorer)

{{#include ../../../banners/hacktricks-training.md}}


Expand Down