T09 · Insecure Skill Coding Practices
- Location
scripts/build-and-deploy.sh:54- Finding
Executable Configuration Injection Through Sourced User Input
- Content
View full analysis
"$CONFIG_FILE" <- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a real website builder and deployer, but it handles deployment secrets and public tracking behavior in ways users should review carefully before installing.
Install only if you are comfortable giving it a Vercel token and allowing it to deploy public sites. Use a narrowly scoped, revocable token; avoid providing Google service-account credential paths; review generated pages for privacy claims before publishing; and treat the local .skill-config file as sensitive.
scripts/build-and-deploy.sh:54Executable Configuration Injection Through Sourced User Input
scripts/build-and-deploy.sh:108Credentials Stored in Plaintext and Vercel Token Exposed Through Process Arguments
scripts/build-and-deploy.sh:218Unescaped Values Injected Into Generated HTML and JavaScript
${IDEA:-A polished product built for the people who need it most.}
``` The generated Next.js component similarly derives client-visible values directly from generated environment configuration: ```typescript const SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL ?? ''; const SUPABASE_ANON_KEY = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY ?? ''; const SUPABASE_ENABLED = !!(SUPABASE_URL && SUPABASE_ANON_KEY); ``` ```typescript const res = await fetch(`${SUPABASE_URL}/rest/v1/waitlist`, { method: 'POST', headers: { 'Content-Type': 'application/json', apikey: SUPABASE_ANON_KEY, Authorization: `Bearer ${SUPABASE_ANON_KEY}`, Prefer: 'return=minimal', }, body: JSON.stringify({ email }), }); ``` ### Technical Analysis The script constructs HTML and Ja ...[truncated 1922 chars]scripts/build-and-deploy.sh:423Mutable Remote Package Downloaded and Executed With npx
The declared description frames the skill as an idle website builder, but the body also collects and persists deployment tokens, optional Google credential paths, and publishes deployed artifacts containing baked configuration values. This mismatch undermines informed consent and can cause users to authorize credential handling and public deployment they did not reasonably expect.
The skill requests a path under a common Google Cloud credential location, which can steer users toward exposing privileged credential material unrelated to simple site deployment. Even though only a path is requested, the workflow institutionalizes credential discovery and persistence in a context that does not clearly justify it.
- If **yes** → ask:
> "What is your Google Application Credentials JSON file path?
> (e.g. /home/you/.config/gcloud/service-account.json)"
Save as `GOOGLE_APPLICATION_CREDENTIALS`.
The page explicitly claims 'No tracking' while analytics code may be injected and activated. This is a stronger variant of the disclosure issue because it is an affirmative false statement about data practices, increasing regulatory, contractual, and reputational risk.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
}
WAITLISTtsx
# Write .env.local for Next.js
cat > "${TARGET_DIR}/.env.local" <<ENVLOCAL
NEXT_PUBLIC_SUPABASE_URL=${SUPABASE_URL}
NEXT_PUBLIC_SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
WAITLISTtsx
# Write .env.local for Next.js
cat > "${TARGET_DIR}/.env.local" <<ENVLOCAL
NEXT_PUBLIC_SUPABASE_URL=${SUPABASE_URL}
NEXT_PUBLIC_SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}
ENVLOCAL
The skill performs sensitive operations requiring environment access and network/deployment capabilities, but it does not declare an explicit tool scope such as allowed-tools or permissions. That increases the chance of overbroad execution in environments that rely on manifest scoping, making secret access and internet actions less visible to users and policy enforcement.
The skill instructs the agent to persist collected tokens and integration values into a dotfile for reuse across sessions. Persistent storage of secrets increases the blast radius of local compromise and creates long-lived credential exposure beyond the immediate deployment action.
### Onboarding Wizard
Ask the user each question in order. Collect the answers, then write them all to `.skill-config` at the end. Present each question clearly — one at a time, conversationally.
---
The onboarding flow asks for a Google Application Credentials JSON path and persists it in a reusable config for a workflow that only injects client-side GA tags. Requesting service-account credential material for this purpose is unnecessary and normalizes collection of higher-sensitivity cloud credentials than the task requires.
The broad trigger phrase for re-running setup can cause the skill to activate and ask for secrets in normal conversation without strong user intent verification. In a system that supports conversational routing, that increases the risk of surprise credential collection and unintended workflow execution.
The skill sources a persistent shell config from the user's home directory that contains secrets, causing those values to enter the shell environment for subsequent commands. This broadens exposure to accidental leakage through logs, child processes, command history, or other tools invoked later in the workflow.
The deployment instructions explicitly export Supabase and analytics values and build them into static client assets before public deployment, yet the skill lacks a clear warning that these values will be embedded into the published bundle. Users may incorrectly assume configuration remains server-side, leading to accidental publication of values they consider secret.
The scaffolded waitlist form collects email addresses and sends them to Supabase without any privacy notice, retention disclosure, or user consent language in the generated page. Collecting personal data without disclosure creates privacy and compliance risk and can mislead end users about how their data will be used.
The generated site states 'No tracking' and 'Your data stays yours' while the script conditionally injects Google Analytics when configured. This is a deceptive privacy representation that can lead to undisclosed data collection and legal/compliance exposure.
The script executes npx create-next-app@latest, which pulls and runs the newest package version at build time without a pinned, reviewed release. This creates a supply-chain risk: a compromised upstream package or breaking change could execute arbitrary code on the operator's machine during scaffolding.
The manifest promises autonomous website building and deployment, but this branch instructs the agent to query gh issue list against the OpenClaw repository. Accessing GitHub issue data is a separate external capability not clearly justified as necessary for building and deploying websites, especially since it may depend on broader GitHub CLI authentication/context.
The setup wizard asks for 'Google Application Credentials JSON path' and stores GOOGLE_APPLICATION_CREDENTIALS, but the only analytics behavior in this file is injecting a public gtag.js snippet using the GA measurement ID. Reading and persisting service-account credential configuration is not justified by the code's stated website scaffold/deploy behavior here.
Detected: suspicious.env_credential_access, suspicious.exposed_secret_literal, suspicious.generated_source_template_injection