T09 · Insecure Skill Coding Practices
- Location
SKILL.md:267- Finding
Upload Workflow Requires Disclosure of API Secrets in Conversation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is a Review concern because it handles upload secrets unsafely and understates its deployment-related actions.
Install only if you are comfortable with an agent handling Aicade upload credentials and changing the project .env file. Do not paste real secrets into chat, do not allow full credential values to be printed, verify .env is ignored by Git, and review any downloaded upload.js or npm dependency changes before running upload commands.
SKILL.md:267Upload Workflow Requires Disclosure of API Secrets in Conversation
scripts/save-aicade-env.mjs:8API Secret Is Mirrored into a Client-Oriented Vite Variable and Stored in Plaintext
SKILL.md:287Mutable Upstream Upload Code Is Retrieved and Executed Without Integrity Verification
SKILL.md:374Declared Security Scope Omits Credential Access, File Modification, Remote Retrieval, and Upload Operations
These instructions normalize soliciting sensitive API keys from the user, persisting them to .env, and operationally reusing them as part of the skill flow. That creates a direct secret-handling channel inside a prompt-building skill, increasing the likelihood of credential theft, accidental disclosure, or misuse if the agent/session is compromised.
The example explicitly encourages echoing full secret values back during upload confirmation, which is a textbook sensitive-data exposure flaw. Even if intended as convenience, it materially increases the chance of credential compromise through transcript retention and observation.
Referenced artifact was not completely inspected
- `scripts/build-aicade-prompt.mjs`
Referenced artifact was not completely inspected
- `scripts/check-aicade-env.mjs`
Referenced artifact was not completely inspected
- `scripts/save-aicade-env.mjs`
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.
- If the stack does not match, only offer the two allowed choices
- Reconfirm the real `upload.js` environment variables before every upload
- For new projects, copy `upload.js` from the official `aicade-ts-bootstrap` repository instead of rewriting it
- If the docs change, update this skill accordingly
These instructions direct the agent to solicit sensitive API credentials and persist them, including secret keys, as part of normal workflow. Having an agent collect secrets in conversation and manage them in plain form is highly dangerous because secrets can be exposed through chat history, telemetry, logs, prompt injection side effects, or accidental repository inclusion.
The workflow explicitly instructs the agent to restate credential values, including secrets, before upload confirmation. Echoing secrets back in plain language dramatically increases disclosure risk because it duplicates sensitive data into chat transcripts, logs, screenshots, and any downstream monitoring systems.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
function loadProjectEnv(cwd) {
const env = {};
for (const name of [".env", ".env.local"]) {
Object.assign(env, parseEnvFile(path.join(cwd, name)));
}
return env;
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
function loadProjectEnv(cwd) {
const env = {};
for (const name of [".env", ".env.local"]) {
Object.assign(env, parseEnvFile(path.join(cwd, name)));
}
return env;
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
function loadProjectEnv(cwd) {
const env = {};
for (const name of [".env", ".env.local"]) {
Object.assign(env, parseEnvFile(path.join(cwd, name)));
}
return env;
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
node save-aicade-env.mjs --cwd /path/to/project --set KEY=VALUE [--set KEY=VALUE ...]
Options:
--cwd Project directory whose .env file should be updated. Default: current working directory
--set One env assignment per flag. Can be repeated.
-h, --help
`);
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
node save-aicade-env.mjs --cwd /path/to/project --set KEY=VALUE [--set KEY=VALUE ...]
Options:
--cwd Project directory whose .env file should be updated. Default: current working directory
--set One env assignment per flag. Can be repeated.
-h, --help
`);
Constructing and writing directly to a project's .env file is credential-handling behavior because this file commonly stores secrets, and this script then populates it with API keys and secret keys. While there is no exfiltration, the behavior can still expose credentials by persisting them in a predictable location that may be read by tooling, bundled incorrectly, or committed accidentally.
function main() {
const args = parseArgs(process.argv.slice(2));
const envPath = path.join(args.cwd, ".env");
const assignments = new Map();
for (const raw of args.sets) {
The skill declares no explicit tool scope while its documented workflow clearly involves network access, environment inspection, and local secret handling. Missing permission boundaries can cause an invoking agent to over-assume allowed capabilities and perform more sensitive actions than users expect.
The manifest presents this as a prompt-building skill, but the instructions expand into collecting, storing, and reusing platform API credentials in project .env files. This scope mismatch is dangerous because users and orchestrators may invoke the skill expecting low-risk prompt assembly while it actually handles secrets and modifies project state.
The skill instructs storing API credentials in the project's .env file without any guidance on secret minimization, filesystem trust, .gitignore protection, or avoiding downstream exposure. In practice this can lead to secret leakage through source control, logs, shared workspaces, or later prompt/context inclusion.
The documented behavior includes upload preparation, environment-variable reconciliation, scaffold management, and operational deployment guidance beyond prompt construction. That hidden expansion of responsibilities increases the chance of unauthorized or surprising actions by an agent operating under an incomplete manifest.
The final confirmation example instructs restating credential values directly in agent output. Echoing secrets in chat or logs creates immediate exposure risk because transcripts are often stored, shared, or visible to unauthorized viewers.
The Security and Permissions section claims the skill does not upload anything by itself, yet earlier sections direct build-and-upload workflow steps and credential handling for upload. This contradiction can mislead users and safety systems about the real operational risk and lead to unsafe trust decisions.
The default prompt uses a very broad invocation phrase ('turn my app idea into an aicade-ready prompt and implementation workflow') that can match ordinary user requests about app building or implementation help. This can cause the skill to activate in unintended contexts, increasing the chance of prompt injection, scope confusion, or accidental use of bundled instructions when the user did not explicitly request this specific skill.
The skill is described as a prompt builder, but this workflow instructs the agent to collect platform credentials, query local environment state, and persist secrets into a project .env file. That expands the skill into secret-handling and local configuration management, creating unnecessary exposure of sensitive data and increasing the chance of credential capture, misuse, or leakage through logs, prompts, or repository commits.
The instructions tell the agent to request API keys and secret keys and save them into .env immediately, but provide no warning about secret sensitivity, local storage risks, logging exposure, or accidental commit risk. In an agent context, this omission is dangerous because users may reveal credentials in chat and the agent may handle them in ways that are not appropriately isolated.
The workflow requires external README validation, stack compliance checks, and possible project reimplementation from an official scaffold, which exceeds the declared purpose of assembling prompts. This broadens the agent's authority and can drive unexpected codebase changes or repository substitution that a user may not anticipate from a prompt-builder skill.
The upload section directs the agent to inspect local environment state, collect upload credentials, persist them, and acquire upload logic from an external scaffold, which is outside the stated prompt-builder function. Combining prompt assembly with deployment credential management materially increases the risk of secret exposure and unintended supply-chain or deployment actions.
Detected: suspicious.exposed_secret_literal