T09 · Insecure Skill Coding Practices
- Location
scripts/anythingllm.sh:21- Finding
Arbitrary Command Execution Through Shell eval
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This AnythingLLM document-search skill is mostly purpose-aligned, but it ships an embedded API key and contains a reachable shell-injection flaw that can run local commands.
Review before installing. Use only with a trusted local AnythingLLM instance, remove and rotate the embedded API key, require an explicit user-provided token, replace eval-based curl construction, and avoid uploading sensitive documents until the destination URL, transport security, and storage behavior are clear.
scripts/anythingllm.sh:21Arbitrary Command Execution Through Shell eval
scripts/anythingllm.sh:13Hard-Coded AnythingLLM Bearer Credential
scripts/anythingllm.sh:12Sensitive API Traffic Permitted Over Plaintext HTTP
The documented purpose is limited to querying and uploading documents, but the behavior reportedly also includes workspace enumeration, document listing, health/auth checks, and a hardcoded default API key. That mismatch is dangerous because it expands access beyond user-expected actions and can facilitate reconnaissance, unauthorized data discovery, or credential misuse—especially severe if a default key is embedded.
The skill invokes shell-based scripts but does not declare any explicit tool scope or allowed-tools boundary. This creates an authorization and review gap: operators and downstream agents cannot clearly tell that the skill can execute shell commands that access local files and networked services, increasing the chance of unintended command execution or data access.
The skill supports uploading files and raw text but does not clearly warn that private/local content will be transmitted to the AnythingLLM service. In a document-oriented skill, this context makes the omission more dangerous because users are likely to provide sensitive PDFs, notes, or proprietary text under the assumption they remain purely local.
The generic api_call function constructs a shell command string containing attacker-influenced values and executes it with eval. Because endpoint and data can include quotes or shell metacharacters, this creates a command injection path in addition to transmitting data externally with authorization headers.
local endpoint="$2"
local data="$3"
local curl_cmd="curl -s -w '\n%{http_code}' -X ${method} \
-H 'Authorization: Bearer ${ANYTHINGLLM_API_KEY}' \
-H 'Content-Type: application/json' \
'${ANYTHINGLLM_URL}/api${endpoint}'"
This call sends user questions to the AnythingLLM chat endpoint together with an authorization token, which is an external transmission of potentially sensitive content. In the context of a private-document RAG skill this behavior is expected, but it still poses confidentiality risk because prompts may contain private or regulated data and the service endpoint is configurable.
EOF
)
curl -s -X POST \
-H "Authorization: Bearer ${ANYTHINGLLM_API_KEY}" \
-H "Content-Type: application/json" \
"${ANYTHINGLLM_URL}/api/v1/workspace/${workspace}/chat" \
The skill sends user-provided questions, uploaded files, and raw text to an HTTP API endpoint without any explicit disclosure or consent prompt. Even if the service is local by default, this still transmits potentially sensitive document contents and queries to another service boundary, which creates privacy and data handling risk.
The script exposes workspaces and health commands that go beyond the declared document query/upload purpose and allow environment discovery. While not directly destructive, these functions expand the skill's capability to enumerate internal resources and confirm authenticated access, which can aid lateral misuse or reconnaissance.
The script contains a default hardcoded API key and uses it automatically for authentication without disclosure. Embedding credentials in a distributable skill risks secret leakage, unauthorized access reuse, and accidental exposure if the script is shared, logged, or committed publicly.