T09 · Insecure Skill Coding Practices
- Location
verify_skill.py:11- Finding
Test workflow writes an unencrypted private key and may leave it on disk after failure
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill does what it says at a high level, but it handles signing keys in ways users should review carefully before trusting it for real artifact signing.
Install only if you understand that this is raw private-key signing, not certificate-chain signing. Do not use the provided plaintext key-generation example for production keys; use encrypted keys or a secure key store, restrict file permissions, and verify exactly which artifact and output path the agent will use.
verify_skill.py:11Test workflow writes an unencrypted private key and may leave it on disk after failure
examples/usage.md:19Usage documentation encourages creation of an unencrypted private-key file without explicit access controls
The skill claims signing with a digital certificate and private key, but the documented behavior only references a PEM private key and detached signature generation. This mismatch can mislead users or downstream agents into assuming certificate-backed trust properties, causing incorrect security decisions about artifact provenance and verification.
The skill exposes shell execution behavior via an example command and implied script invocation, but it does not declare any tool scope restrictions such as permissions or allowed-tools. In an agent environment, missing scope declarations can allow broader-than-expected command execution or make review and policy enforcement harder, increasing the chance of misuse of file paths and key material.
The example generates a private key and writes it to disk using NoEncryption(), which stores the key unprotected at rest. Even though this is presented as a testing example, readers may reuse it in real workflows, and compromise of the PEM file would allow unauthorized signing of artifacts and undermine trust in distributed binaries.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 3. Use the sign_artifact.py script
print("Running sign_artifact.py...")
script_path = os.path.join("scripts", "sign_artifact.py")
result = subprocess.run(
["python", script_path, "test_artifact.txt", "test_private.pem"],
capture_output=True, text=True
)