T09 · Insecure Skill Coding Practices
- Location
- SKILL.md:39
- Finding
- Persistent user credential is not protected by enforced filesystem permissions or version-control exclusions## Vulnerability Details **File Location**: `SKILL.md:39`, `SKILL.md:102-104`, and `README.md:134-146` **Vulnerability Type**: Insecure plaintext credential storage **Risk Level**: Medium ### Vulnerable Code `SKILL.md:39`: ```text Do not request `user_key` until an order operation actually needs it; when the user sends it, the Agent saves it to `{baseDir}/user_key.txt` and never asks the user to manage that local file. ``` `SKILL.md:102-104`: ```text 1. Read `{baseDir}/user_key.txt`. 2. If it is absent or empty, pause the order operation. In the user's language, ask them to open `https://auth.journione.ai`, verify their email address to sign in, copy the `user_key` in the form `uk_xxxxxxxx`, and provide it. If the user has trouble registering or signing in, tell them that the Agent can open the link in its built-in browser and help them complete the process. Save the supplied key to that file, then continue. 3. If an HTTP 401 or an error containing `unauthorized` is returned, delete `{baseDir}/user_key.txt`, stop the order workflow and ask the user in their language to verify their email and sign in again for a new key. If they have trouble, offer the same built-in-browser assistance. ``` `README.md:134-146`: ```markdown You can search hotels, inspect hotel and room details, compare live rates, and verify availability without a `user_key`. When you are ready to create, view, cancel, or pay for a booking: 1. Sign in with Google at [auth.journione.ai](https://auth.journione.ai). 2. Copy your `user_key` and save it as `user_key.txt` in the installed `hotel-booking-ai` folder. Your AI agent can also guide you through this step when you start an order operation. 3. On macOS or Linux, restrict access to the file: ```bash chmod 600 user_key.txt ``` Never commit `user_key.txt`. It is excluded by `.gitignore` and should stay only on your device. ``` ### Technical Analysis The runtime instructio ...[truncated 2647 chars]
- Remediation
- ## Remediation Suggestions 1. **Use protected secret storage** - Prefer the operating system keychain, the AI client's secret manager, or another credential store designed for authentication material. - Store only a reference to the secret in the Skill directory. 2. **Enforce restrictive permissions** - If a file is unavoidable, create it atomically with owner-only mode `0600`. - Reject symlinks and avoid a check-then-write sequence. - Verify ownership and effective permissions after creation. - On platforms without POSIX modes, use the platform's equivalent access-control mechanism. 3. **Keep credentials outside the repository** - Store the key in a client-specific configuration or data directory rather than inside a Git working tree. - Separate mutable secret state from installed Skill files. 4. **Add version-control protection** - Add a root `.gitignore` containing: ```gitignore /user_key.txt ``` - Consider adding a pre-commit secret scan as defense in depth. - Correct the documentation so it does not claim that an absent `.gitignore` already provides protection. 5. **Minimize credential lifetime** - Provide a user-visible sign-out operation that securely removes the stored key. - Avoid retaining the credential longer than needed where session-based storage is available. - Ensure logs, prompts, errors, URLs, and diagnostics never include the key. 6. **Align all documentation** - Apply the same storage and authentication rules to the canonical and translated Skill documents.
