REST API
The HTTP API style nearly every connected device uses to reach its cloud, and that its mobile app uses to reach the same cloud. Resources as URLs, verbs as intent, JSON as payload.
REST is an architectural style for HTTP APIs. In practice it means resources identified by URLs, HTTP verbs expressing intent, JSON bodies, and stateless requests that each carry their own authentication. It is what the mobile app of essentially every connected device speaks, and therefore where most of a product's real attack surface lives.
The shape
GET /api/v1/devices list
POST /api/v1/devices create
GET /api/v1/devices/1042 read one
PUT /api/v1/devices/1042 replace
PATCH /api/v1/devices/1042 partial update
DELETE /api/v1/devices/1042 remove
POST /api/v1/devices/1042/reboot an action that is not CRUD
Status codes carry the outcome: 200 fine, 201 created, 400 your request was malformed, 401 not authenticated, 403 authenticated but not allowed, 404 not there, 429 rate limited, 5xx their problem. The 401 versus 403 distinction is worth reading carefully during an assessment, because it tells you whether the server distinguishes the two at all.
Authentication is normally a bearer token or an API key in a header, sometimes a signed request, and the token is stateless: the server does not remember you between requests.
Why it dominates the device attack surface
A modern IoT product has three clients of the same API: the device, the mobile app, and the vendor's web console. The device may speak MQTT for telemetry, but provisioning, firmware manifests, user accounts and sharing all go over REST. That makes the API, not the device, the place where the interesting authorization decisions are made and where they are most often wrong.
The mobile app is also the documentation. Proxying it once yields the base URL, the authentication scheme, the identifier format and most of the endpoint list, for free.
What to look at
- Authorization on every object, on every verb. This is
idor, and it is the most commonly found flaw in this class of API. AGETthat is protected and aDELETEon the same path that is not, is normal. - Undocumented and versioned endpoints.
/api/v1/still being live after/api/v2/shipped is routine, and the old version often lacks the checks added to the new one. - Mass assignment. Sending extra fields (
"role": "admin","owner_id": 7) in aPATCHbody that the server binds straight onto its model. - Tokens. Where they live on the device, how long they last, whether they can be refreshed forever, whether a JWT's signature is actually verified, and whether
alg: noneis accepted. - Rate limiting and enumeration. Registration, password reset, and device-claim endpoints that allow unlimited attempts.
- Verbose errors. Stack traces and SQL fragments in
5xxbodies. - CORS and the web console, when there is one.
On the device side
The device's own credentials for this API are in its firmware or its NVS. A single API key shared across a whole product line is a common finding, and it converts one dumped device into access to the fleet's API. Look for the base URL as a string, then work backwards to whatever holds the token.
Pitfalls
403does not always mean the check exists. Some servers return403for anything they cannot parse. Verify with a request you know should succeed.- Testing against production. Rate limits, alerting, and other people's data. Use your own account and your own device, and say so in the report.
- Assuming the app shows the whole API. Server-side endpoints the app never calls are still reachable; the versioned path and the OpenAPI document, if exposed, reveal more.
- Confusing
401with logged out. An expired token and an insufficient scope look similar and mean very different things.
What it pairs with
idor is the flaw you are most likely to find, mitmproxy is how you watch the app, tls is what you have to get through first, and hardcoded-secrets covers the credentials on the device.