T09 · Insecure Skill Coding Practices
- Location
SKILL.md:69- Finding
Unsafe Execution of Repository-Controlled Environment File
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 69–75
Vulnerability Type: Unsafe shell sourcing of a local configuration file
Risk Level: HighVulnerable Code
bash ( set -a; [ -f .env.local ] && . ./.env.local; set +a; curl -sS -H "Authorization: Bearer $SERVICEGRAPH_API_KEY" \ 'https://api.servicegraph.co/v1/datasets/pro_services/fields' )Technical Analysis
The authentication procedure instructs the Agent to load
.env.localwith the shell dot command:bash . ./.env.localThis command executes the file as shell code rather than parsing it as passive key-value configuration. If the project directory or
.env.localis attacker-controlled or compromised, arbitrary shell commands embedded in that file will execute with the privileges of the Agent's shell.The use of
set -aalso causes all subsequently assigned variables to be exported. Although the displayedcurlcommand sends onlySERVICEGRAPH_API_KEY, exporting every variable from the file unnecessarily broadens the environment inherited by child processes.Reading one API credential is necessary for the Skill's stated functionality, but executing the entire configuration file is not. This therefore violates least-privilege principles and creates a command-execution boundary where only data parsing is required.
Attack Path
- An attacker gains the ability to create or modify
.env.localin the working directory, such as through a malicious project archive, compromised repository content, or prior local write access. - The attacker inserts shell commands into that file. These commands could inspect local files, alter project content, or make attacker-controlled network requests.
- The user invokes the Skill without a valid preconfigured authentication session.
- Following the documented authentication recipe, the Agent runs the provided shell wrapper.
- The shell executes all commands in
.env.localbefore invokingcurl. - The ma ...[truncated 776 chars]
- An attacker gains the ability to create or modify
- Remediation
View remediation
Remediation Suggestions
- Do not source
.env.localor any repository-controlled dotenv file as shell code. - Prefer the documented ServiceGraph MCP integration so OAuth credentials remain within the harness sandbox.
- If REST authentication is required, obtain
SERVICEGRAPH_API_KEYfrom an already configured process environment rather than executing a project file. - If dotenv support is necessary, use a parser that treats the file strictly as data and does not perform shell expansion, command substitution, variable interpolation, or evaluation.
- Extract only the required variable instead of exporting all entries. Reject duplicate keys and malformed records.
- Validate the resulting credential against the expected API-key syntax, such as an anchored allowlist pattern for
vk_keys, before placing it in an HTTP header. - Ensure
.env.localhas restrictive permissions, is excluded from version control, and is not accepted from untrusted project content. - Keep the token out of command output and model context. Disable verbose HTTP tracing and redact the
Authorizationheader from logs. - Pin outbound requests to the expected HTTPS origin,
api.servicegraph.co, and avoid forwarding the authorization header across redirects to other hosts. - Run the HTTP operation in a restricted environment with minimal filesystem access, a narrow outbound-network allowlist, and no unrelated credentials.
A safer approach is to require the key to be present in the existing environment and fail closed when it is absent:
bash : "${SERVICEGRAPH_API_KEY:?Set SERVICEGRAPH_API_KEY in the trusted process environment}" case "$SERVICEGRAPH_API_KEY" in vk_[A-Za-z0-9_-]*) ;; *) printf '%s\n' "Invalid SERVICEGRAPH_API_KEY format" >&2; exit 1 ;; esac curl --fail --silent --show-error \ -H "Authorization: Bearer $SERVICEGRAPH_API_KEY" \ 'https://api.servicegraph.co/v1/datasets/pro_services/fields'- Do not source
