The password in last year's file
A developer pastes a shop's payment password into a file to test something. They commit the file. The next morning they delete the line and commit again.
Everyone thinks it is gone. A year later a stranger reads the old version of the file. The password still works.
The one rule
Warning
This lab is an application that hides fake secrets on purpose. Search your own private copy and nothing else. It has no way out to the internet. Never go looking for secrets on a site or code store that is not yours. In the UK that is a crime under the Computer Misuse Act 1990.
By the end of this lesson
Note
I can find a secret in the wrong place and say where it belongs.
Key words
| Word | What it means | Example |
|---|---|---|
| Secret | a password, key or token that must stay private | |
| Environment variable | a named setting given to a program when it starts | DB_PASSWORD |
| Secrets manager | a locked store that hands secrets only to programs allowed them | |
| Commit history | every earlier version of every file in a code store | |
| Rotate | to replace a secret with a new one | |
| Container image | a packed copy of a program and its files |
The cells students fill in are left blank in this preview.
Secrets leak from many places
A secret leaks wherever a copy of it can be read by someone it was not meant for. Code is only one place.
It can sit in a source file, in old commits or in a container image. It can sit in a settings file, in a log, or in a script sent to every visitor's browser. A secret the browser needs is a secret everybody has.
Worked example: where each copy lives
| Place | Who can read it | Better |
|---|---|---|
| A source file | Anyone with the code | Read it from the environment |
| Old commits | Anyone with a copy of the history | Rotate it, then clean the history |
| A container image | Anyone who can pull the image | Give it at run time, not at build time |
| A script sent to browsers | Every visitor | Keep it on the server |
| A log file | Everyone who reads logs | Never print secrets |
The cells students fill in are left blank in this preview.
Look at the application in your lab
Your lab runs WrongSecrets. Start it, then run these three. They only look. The first asks if the application is healthy. The second asks which management pages it offers to anybody. The third shows the first characters of a script it sends to every visitor.
Is the application healthy?
curl -s -w "\n" http://wrongsecrets:8080/actuator/healthShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Which management pages does it offer?
curl -s http://wrongsecrets:8080/actuator | grep -o 'actuator/[a-z]*' | sort -uShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
The start of the script every visitor gets
curl -s http://wrongsecrets:8080/js/index.js | head -n 1 | cut -c 1-120Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
What the three answers tell you
The first prints a short line that ends "status":"UP". The second prints three names: auditevents, health and info. Ask which of those a stranger should not read.
The third prints scrambled-looking code. It is scrambled, not locked. The browser must read all of it to run it, and so must you.
A common mistake
Warning
Many people think deleting a secret from a file removes it. It does not. Old versions stay in the history, in every clone and in every image built before. Treat any secret that was ever exposed as spent. Rotate it first. Then clean up.
A secret belongs in a store
The program asks for the secret when it starts. The secrets manager checks who is asking and hands it over. Nothing is written in the code or the image.
Give each program only the secrets it needs. Rotate them on a plan, so that a leak is only useful for a short time.
Secrets have shapes a program can find
Many secrets look alike. A cloud key starts with AKIA and has 20 letters and digits. A private key file starts with a line of dashes and the words BEGIN. A line like password = "..." holds a value.
Scanners search for these shapes in code and history. They find many but not all. Treat a find as a prompt to rotate.
A tiny scanner
lines = [
"name = shop",
"key = AKIAABCDEFGHIJKLMNOP",
"password = hunter22",
]
# Add a fourth line that holds a secret shape, then press Run.
number = 0
for line in lines:
number = number + 1
if "AKIA" in line or "password" in line:
print("check line", number)