T09 · Insecure Skill Coding Practices
- Location
scripts/agent_boarding_pass.py:68- Finding
Forgeable boarding passes used as authorization credentials
- Content
View full analysis
Vulnerability Details
File Location:
scripts/agent_boarding_pass.py:68, 96-105; authorization workflow documented atSKILL.md:86-91
Vulnerability Type: Unkeyed digest used as proof of authenticity
Risk Level: HighComplete Code Snippet
python card = { "pass_type": "lgd-agent-boarding-pass", "agent": a.agent, "issued_at": now.isoformat(timespec="seconds"), "expires_at": expires, "allow": a.allow or [], "evidence_sha256": ev, } card["fingerprint"] = sha256_of( json.dumps(card, ensure_ascii=False, sort_keys=True) )Verification reconstructs the same public data and compares its unkeyed SHA-256 digest:
python body = {k: card[k] for k in ( "pass_type", "agent", "issued_at", "expires_at", "allow", "evidence_sha256" ) if k in card} checks.append(( "指纹防篡改", bool(card.get("fingerprint")) and sha256_of( json.dumps(body, ensure_ascii=False, sort_keys=True) ) == card.get("fingerprint"), "重算一致" if checks and sha256_of( json.dumps(body, ensure_ascii=False, sort_keys=True) ) == card.get("fingerprint") else "不一致(已被篡改或非本体系签发)" ))The documented workflow assigns an authorization role to this check:
text 4. Inject the credential into a system prompt or upload to repo/ticket as trust anchor. 5. The receiving agent recomputes the fingerprint and checks expiry before executing. 6. Only after permission match and non-expiry is access granted.Technical Analysis
The fingerprint is an ordinary SHA-256 digest over fields included in the boarding pass. It does not use a secret signing key, a trusted private key, or any other issuer-only material.
SHA-256 can establish that data matches a supplied digest, but it cannot identify who produced that data. Any party able to construct a boarding-pass JSON document can choose an arbitrary agent identity, permission allowlist, evidence hashes, and expiry, then calculate the corresponding valid fingerprint.
...[truncated 2218 chars]
- Remediation
View remediation
Remediation Suggestions
- Replace the unkeyed fingerprint with a digital signature created using an issuer-held private key, such as Ed25519.
- Configure verifiers with pinned, trusted issuer public keys and reject unknown issuers or unsupported signature algorithms.
- Sign a canonical representation of all security-relevant fields. Include at least:
- issuer identity and key identifier;
- subject agent identity;
- permission allowlist;
- evidence hashes;
- issuance and expiry times;
- intended audience;
- a unique pass identifier or nonce;
- schema and signature-algorithm versions.
- Verify the signature before trusting any identity, permission, expiry, or evidence field.
- Validate the intended audience and issuer in addition to checking expiry, preventing valid passes from being replayed in unrelated systems.
- Define clock-skew limits, maximum validity periods, replay handling, revocation behavior, and key-rotation procedures.
- Do not describe the current unkeyed hash as a signature, issuer-authentication mechanism, or trust anchor. If cryptographic issuer authentication is not intended, label it only as an accidental-corruption checksum and prohibit its use for access-control decisions.
- Add negative tests proving that changing permissions, creating a pass without the issuer's private key, using an unknown issuer, or replaying a pass for another audience causes verification to fail.
