T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:458
- Finding
- Selective Disclosure Function Exposes the Complete Authorization Mandate<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:458-486` **Vulnerability Type**: Sensitive authorization-policy disclosure **Risk Level**: Medium ### Vulnerable Code ```python def create_selective_disclosure(mandate: dict, clause_path: str) -> dict: """Create a selective disclosure proof for a specific mandate clause. Reveals only the requested clause while proving it belongs to the full mandate via the registered hash. """ # Extract the specific clause value keys = clause_path.split(".") value = mandate for key in keys: if key.endswith("]"): field, idx = key[:-1].split("[") value = value[field][int(idx)] else: value = value[key] # Compute the full mandate hash (verifier already has this from the chain) mandate_bytes = json.dumps(mandate, sort_keys=True).encode("utf-8") full_hash = hashlib.sha256(mandate_bytes).hexdigest() return { "clause_path": clause_path, "clause_value": value, "full_mandate_hash": full_hash, "full_mandate": mandate, # Provided to verifier under NDA/escrow "verification_method": "sha256_json_sorted_keys", } ``` ### Technical Analysis The function claims to reveal only a requested mandate clause, but the returned object also contains the complete mandate through the `full_mandate` field. The example mandate contains potentially sensitive information such as the human principal's identity, approved vendors, permitted actions, budget ceiling, agent identifier, and authorization validity period. A hash does not provide selective disclosure by itself. Giving the verifier the complete preimage defeats the confidentiality objective and exposes substantially more information than is necessary to prove that one clause was authorized. ### Attack Path 1. A dispute participant or verifier requests proof that a particular action was authorized. 2. The application invokes `create_selec ...[truncated 1128 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove the complete mandate from the disclosure object: ```python return { "clause_path": clause_path, "clause_value": value, "commitment": clause_commitment, "proof": merkle_proof, "verification_method": "merkle_sha256", } ``` 2. Use a genuine selective-disclosure design, such as: - A Merkle tree with one independently committed mandate claim per leaf. - Signed per-claim credentials. - An established selective-disclosure credential format. - A zero-knowledge proof where confidentiality requirements justify it. 3. Define an explicit disclosure policy specifying which fields each verifier role may receive. 4. Redact principal identifiers, vendor lists, budget ceilings, and unrelated mandate clauses from dispute evidence by default. 5. Add tests asserting that generated proof objects never contain the original mandate or unrelated fields. 6. If exceptional workflows require full disclosure, implement them as a separate, explicitly named function with recipient authorization, encryption, audit logging, and informed operator approval. ]]>
