Unit 8: APIs and how modern apps talk · Lesson 2 of 5 · 20 min

Calling an API with a token

Get a bearer token, send it the right way and review what the API returns about you.

mission

You are
The analyst reviewing the shop's API.
Situation
The profile endpoint /api/v1/me is the first thing the mobile app calls after sign-in.
Goal
Call it with and without a token and review every field it returns.
Hand in
The fields /api/v1/me returns and any that should not be there.

A JWT, three parts

eyJhbGciOi....eyJzdWIiOi....c2lnbmF0dX...
  1. 1eyJhbGciOi...header: algorithm
  2. 2.eyJzdWIiOi...payload: who and until when
  3. 3.c2lnbmF0dX...signature: proves it was not changed
01

Without a token

learner@web-lab
curl -si http://127.0.0.1:8000/api/v1/me | grep -iE '^(HTTP|www-authenticate)'
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="shop"

you should see 401 and a WWW-Authenticate header naming the scheme the API expects.

curl
Sends web requests and prints the response. Built into Linux, macOS and Windows 10 and later.
grep
Prints the lines of text that match a pattern. Built into Linux and macOS.
02

Get a token

Keep the token in a file, not in a URL.

learner@web-lab
curl -s -d @shop-account.txt http://127.0.0.1:8000/api/token | jq -r .access_token > token.txt
wc -c < token.txt
214

you should see A token of a couple of hundred characters.

jq
Picks fields out of JSON and reshapes it. Install with sudo apt install jq, or brew install jq on a Mac.
wc
Counts lines, words and bytes. Built into Linux and macOS.
03

Call the profile endpoint

learner@web-lab
curl -s -H "Authorization: Bearer $(cat token.txt)" http://127.0.0.1:8000/api/v1/me | jq .
{
  "user": "learner",
  "email": "learner@shop.internal",
  "role": "customer",
  "password_hash": "pbkdf2_sha256$600000$q2Vt8k1sR9mZ$ObOoXw2Lu84Fh+C0wkMbWgSyKaZD+KLIFo3ynohSNYk="
}

you should see Your user, email and role, and one field that has no business leaving the server.

cat
Prints the contents of one or more files. Built into Linux and macOS.
04

List the fields

learner@web-lab
curl -s -H "Authorization: Bearer $(cat token.txt)" http://127.0.0.1:8000/api/v1/me | jq -r 'keys[]'
email
password_hash
role
user

you should see Four fields. The password hash is excessive data exposure: the app never needs it.

defender tip APIs often return whole database rows and leave hiding to the app. Review what the API sends, not what the screen shows.

The profile response

Today
return user_row

Every column, hash included.

Fix
return {"user": u.name, "email": u.email, "role": u.role}

An explicit allowlist of fields.

What a defender takes away

  1. 1Send tokens in the Authorization header, never in the URL.
  2. 2401 with WWW-Authenticate is the right answer to a missing token.
  3. 3Review raw API responses for fields the client never uses.

Questions

0 of 3 solved

Answer each one from what you find on your lab machine.