[ norboten ]
python · lab python-07

The Client That Leaks Its Token

· about 40 minutes · runs on ubuntu-26.04-devops · unrated

An unrated lab. It runs on your machine with no account and no network, and everything about it — the faults, the checks, the hints and the reference solution — is in the repository. An attempt on it is recorded on your profile and never moves a rating: only rated labs do. Rated and unrated labs.

The briefing

partner-sync.service runs /opt/partner/sync.py every few minutes. It reads an API token from /etc/partner/token, asks the partner API for the day's orders, and writes them to /var/lib/partner/orders.json.

The security review found three things. The token is in the journal — the client logs the request it is about to make, headers and all, and logs the URL again when a request fails. /etc/partner/token is readable by every account on the machine. And the service runs as root although it needs nothing that root can do.

The partner's API is simulated on this machine by partner-api.service on http://127.0.0.1:8977, which accepts the token in /etc/partner/token.

What is expected, and graded:

  1. The sync still works: run by hand or by the service, it writes the orders and exits 0.
  2. Neither the journal nor the sync's own log holds the token — not on a successful run, not on a failing one, and not when the log level is raised to DEBUG.
  3. /etc/partner/token can be read by its owner only, and that owner is not every user of the machine.
  4. partner-sync.service runs as a system account of its own, not as root, and that account cannot be logged in to.

You have root through sudo. The token itself stays as it is.

What is graded

The machine is checked, rebooted, and checked again. A check passes only if it passes both times.

CheckObjective
01_the_sync_still_worksKeep a credential out of the log, whatever is logged
02_the_journal_holds_no_tokenKeep a credential out of the log, whatever is logged
03_the_token_file_is_privateKeep a credential out of reach of other accounts on the machine
04_the_service_is_not_rootGive a service only the access it needs, and no interactive account

Start it

  1. 2Labs
  2. python-07select this one
  3. udownload it
  4. sstart the machine

Reading

Where the lab's hints send you, level by level, as you ask for them (h, then l opens a journal section in the TUI).

Theory for this lab

4 questions on the same topic, in the lab's Theory tab. They never affect the lab's grade. Three of them, to answer here:

Question 1

What does this print?

import urllib.error
e = urllib.error.HTTPError("https://api.example.com/orders?token=ptk_live_secret",
                           403, "Forbidden", {}, None)
print("secret" in str(e), "secret" in e.url)
Question 2

A client authenticates with a bearer token. Which of these put the token somewhere other people can read it? Select all that apply.

Question 3

`/etc/app/token` is `-rw------- 1 appsvc appsvc` and `/etc/app` is `drwx------ 2 root root`. The service runs as `appsvc`. What happens when it reads the token?