Challenge 70 ☆☆

Welcome to challenge Challenge 70.

Challenge 70: Find the Secret in the Claude Skill Bundle

Claude skills are distributed as exported .skill bundles: a zip archive containing a folder with a SKILL.md that describes when to use the skill, plus any scripts and reference material the skill needs. The whole bundle is unpacked on the machine that installs it.

That makes a skill bundle a great hiding place, because reviewers tend to read the SKILL.md and stop there. The interesting part is usually in the files next to it.

This application ships a Claude skill called incident-reporter. The exported skill bundle lives in the resource folder and is served as a download at /skills/claude/incident-reporter.zip.

Download the bundle, unpack it, and work out the token the uploader authenticates with.

Note

The SKILL.md is clean. Reading only the entry point of a skill is not a review.

💡 Tip: Secrets are often strings, numbers, or encoded values. Copy and paste exactly what you find.

Download and unpack the exported skill bundle:

curl -sO http://localhost:8080/skills/claude/incident-reporter.zip
unzip incident-reporter.zip

The SKILL.md only points at the bundled uploader. Open incident-reporter/scripts/upload_report.py and look at UPLOAD_TOKEN_B64.

That value is not the answer yet: the author base64 encoded it to stop the secret scanner from complaining. Decode it, for example with base64 -d, and submit the decoded token.

Why a skill bundle needs the same review as your source code

A skill bundle is shipped software. It contains executable scripts, it runs on developer machines and in CI, and it is installed by people who did not write it. Treating it as "just some markdown" is how secrets end up being distributed at scale.

Two failures stack up in this challenge:

  • The token is committed inside the bundle, so everyone who installs the skill receives a working shared credential.

  • When sharing the skill inside Claude, everyone with access to the skill, will have access to the secret.

  • The token is base64 encoded, which is encoding, not encryption. It stops a naive secret scanner from firing, and it stops nobody else. Anyone with the bundle can decode it in one command.

The second point is the more dangerous of the two, because it converts a detectable problem into an undetectable one. The scanner goes quiet, the finding disappears from the backlog, and the credential stays valid for years.

What to do instead:

- Read credentials from the environment or a secret manager at runtime, and fail loudly with a clear message when they are absent.
- Never "fix" a secret scanner finding by encoding, splitting or obfuscating the value. Fix it by removing the secret and rotating it.
- Review every file in a skill bundle, not just the `SKILL.md`. Scripts, reference documents and sample configuration are all part of the attack surface.
- Verify the bundle in CI: unpack it and run your secret scanner over the extracted contents, including a base64-aware ruleset.
- Publish bundles from a build pipeline that has no access to production credentials in the first place.
Note

Encoding is not a security control. If the only thing standing between an attacker and your credential is a base64 -d, the credential is public.


📦 Claude skill bundle: incident-reporter

This application ships an exported Claude skill bundle. The backend serves the exported .skill file as a zip download at /skills/claude/incident-reporter.zip.

Step 1 — download and unpack the bundle:

curl -sO https://wrongsecrets.herokuapp.com/skills/claude/incident-reporter.zip
unzip incident-reporter.zip
find incident-reporter -type f
⬇ Download incident-reporter.zip

Step 2 — the SKILL.md is clean. Look at what it tells the agent to run:

grep -r TOKEN incident-reporter/

💡 The token you find is not the answer yet — the author "hid" it from the secret scanner. Submit the value the uploader actually authenticates with.