T09 · Insecure Skill Coding Practices
- Location
SKILL.md:39- Finding
Persistent user credential is not protected by enforced filesystem permissions or version-control exclusions
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:39,SKILL.md:102-104, andREADME.md:134-146
Vulnerability Type: Insecure plaintext credential storage
Risk Level: MediumVulnerable 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
View remediation
Remediation Suggestions
-
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.
-
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.
- If a file is unavoidable, create it atomically with owner-only mode
-
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.
-
Add version-control protection
-
Add a root
.gitignorecontaining: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
.gitignorealready provides protection.
-
-
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.
-
Align all documentation
- Apply the same storage and authentication rules to the canonical and translated Skill documents.
-
