Back to skill

Security audit

Secure Workspace

Security checks for vulnerabilities and agentic risk

Overview

This skill is meant to encrypt workspace secrets, but its recommended decrypt workflow can run decrypted secret files as shell code and exposes secrets in the live shell environment.

Review before installing. Use this only if you understand age key management and avoid sourcing encrypted files from repositories, backups, or other people. Prefer decrypting secrets for a specific command or parsing a strict dotenv format, and treat /root/.age/key.txt or $HOME/.age/key.txt as highly sensitive private key material.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:23
Finding

Unauthenticated Decrypted Content Is Executed as Shell Code

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:23 and scripts/secure/setup.sh:54-56
Vulnerability Type: Execution of unauthenticated decrypted content
Risk Level: High

The documented workflow recommends decrypting an .age file and immediately sourcing the resulting plaintext into the current shell.

Vulnerable code in SKILL.md:23:

bash
source <(bash scripts/secure/decrypt.sh scripts/secure/secrets.env.age)

Vulnerable code in scripts/secure/setup.sh:54-56:

bash
echo "[*] Para descifrar:"
echo "    source <($SCRIPTS_DIR/decrypt.sh $SCRIPTS_DIR/secrets.env.age)"

Technical Analysis

The source command interprets every statement in the decrypted file as shell code within the caller's current shell. The workflow assumes that successful age decryption establishes that the plaintext was authored by a trusted party.

Recipient-based age encryption provides confidentiality and ciphertext integrity, but it does not authenticate the ciphertext's author. The setup workflow displays the public key and explicitly suggests sharing it with other hosts in scripts/secure/setup.sh:21-24. Anyone who obtains that public key can create a valid ciphertext containing arbitrary shell commands.

Consequently, an attacker who can replace or introduce the encrypted secrets file does not need the private key. The attacker only needs the public key to produce a ciphertext that decrypts successfully. When the victim follows the documented command, the malicious plaintext is executed rather than treated strictly as environment-variable data.

Attack Path

  1. The attacker obtains the recipient public key, which the setup script displays and recommends sharing.
  2. The attacker creates plaintext containing arbitrary shell commands, potentially mixed with plausible environment-variable assignments.
  3. The attacker encrypts that payload to the victim's public key using age.
  4. The a ...[truncated 1373 chars]
Remediation
View remediation

Remediation Suggestions

  1. Do not source decrypted content directly. Remove all recommendations that pipe decrypted output into source, eval, or another command interpreter.

  2. Parse secrets as data using a strict format. Use a format such as JSON and an established parser, or enforce a narrowly defined environment-file grammar. Permit only explicitly allowlisted variable names and plain values. Reject shell operators, command substitutions, process substitutions, function definitions, redirections, and multiline executable constructs.

  3. Authenticate distributed ciphertexts. If encrypted files can be supplied by other users or distribution systems, require a detached digital signature from a separately trusted signing key. Verify that signature before decryption or parsing. Encryption to a public recipient key must not be treated as proof of authorship.

  4. Use a restricted import process. After validation, assign approved values without evaluating them as shell syntax. For example, have a parser emit structured key/value records and use safe assignment mechanisms rather than source.

  5. Protect temporary plaintext if a file is unavoidable. Create it with restrictive permissions in a trusted directory, prevent symlink attacks, avoid predictable names, and remove it reliably with a cleanup trap. Prefer keeping values in memory where feasible.

  6. Harden repository and artifact controls. Require review and signature verification for changes to encrypted secret artifacts so unauthorized replacements are detected before use.

  7. Make key-path behavior consistent. The checked-in helper scripts use /root/.age/key.txt, while the versions generated by setup.sh use $HOME/.age/key.txt. Standardize the path and avoid implying that root execution is required.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The stated purpose emphasizes protecting secrets by encrypting them, but the documented behavior also includes decryption, sourcing decrypted content into the current shell, and reliance on a private key stored at /root/.age/key.txt. This mismatch is dangerous because it hides sensitive runtime behaviors that expose plaintext secrets and access a high-value local credential, making operators less likely to apply appropriate safeguards.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 22)May include surrounding context.

md
bash scripts/secure/setup.sh

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 37)May include surrounding context.

md
bash scripts/secure/setup.sh

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 25)May include surrounding context.

md
bash scripts/secure/setup.sh

# 2. Cifrar un secreto
echo 'export API_KEY="..."' | bash scripts/secure/encrypt.sh scripts/secure/secrets.env.age

# 3. Descifrar al vuelo
source <(bash scripts/secure/decrypt.sh scripts/secure/secrets.env.age)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/secure/setup.sh (reported line 52)May include surrounding context.

sh
bash scripts/secure/setup.sh

# 2. Cifrar un secreto
echo 'export API_KEY="..."' | bash scripts/secure/encrypt.sh scripts/secure/secrets.env.age

# 3. Descifrar al vuelo
source <(bash scripts/secure/decrypt.sh scripts/secure/secrets.env.age)

Credential Access

High
Category
Privilege Escalation
Confidence
89% confidence
Finding

This decryption workflow outputs secret material and immediately sources it into the shell, which is a form of credential exposure in plaintext during runtime. In context, the risk is elevated because the skill is specifically designed to handle API keys and tokens, and the documentation normalizes a pattern that can leak credentials to the environment or adjacent processes.

Content

Scanner excerpt · SKILL.md (reported line 28)May include surrounding context.

echo 'export API_KEY="..."' | bash scripts/secure/encrypt.sh scripts/secure/secrets.env.age

3. Descifrar al vuelo

source <(bash scripts/secure/decrypt.sh scripts/secure/secrets.env.age)

text

## Archivos

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/secure/setup.sh (reported line 53)May include surrounding context.

sh
echo ""
echo "[*] AHORA: cifra tus secrets manualmente:"
echo "    echo 'export API_KEY=xxx' | $SCRIPTS_DIR/encrypt.sh $SCRIPTS_DIR/secrets.env.age"
echo "    rm -f /ruta/al/archivo.original"
echo ""
echo "[*] Para descifrar:"
echo "    source <($SCRIPTS_DIR/decrypt.sh $SCRIPTS_DIR/secrets.env.age)"

Credential Access

High
Category
Privilege Escalation
Confidence
85% confidence
Finding

The script recommends source <(decrypt.sh secrets.env.age), which decrypts secrets and directly executes the resulting plaintext as shell code in the current shell. If the encrypted file is tampered with, or if users place anything beyond simple variable assignments inside it, this can lead to arbitrary command execution and exposure of sensitive values in a highly privileged shell context.

Content

Scanner excerpt · scripts/secure/setup.sh (reported line 56)May include surrounding context.

sh
echo "    rm -f /ruta/al/archivo.original"
echo ""
echo "[*] Para descifrar:"
echo "    source <($SCRIPTS_DIR/decrypt.sh $SCRIPTS_DIR/secrets.env.age)"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares shell-capable behavior via bash commands and required executable dependencies, but does not declare any explicit tool scope or permissions boundary. This is dangerous because consumers and automated agents cannot clearly determine what execution privileges the skill expects, increasing the risk of over-broad shell access and unintended command execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill instructs users to source decrypted secrets directly into the current shell using process substitution, which places plaintext credentials into the live environment without any warning. This is dangerous because secrets can be exposed through shell history, child processes, debugging output, crash dumps, or later commands that print environment variables.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script invokes age -d with /root/.age/key.txt, which is access to a sensitive credential file, but there is no confirmation prompt, warning comment about the security implications, or user-facing disclosure beyond basic usage text. For code files, sensitive credential access should have some visible warning unless clearly disclosed as part of the skill behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Line L10 accesses /root/.age/key.txt to extract a public key, which is a credential-related location under root's private key material directory. Although the script comments describe usage, they do not warn the user that it reads from a root-owned key file or depends on local key material, and there is no runtime notice before doing so.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/secure/setup.sh (reported line 12)May include surrounding context.

sh
# 1. Generar par de llaves
AGE_DIR="$HOME/.age"
mkdir -p "$AGE_DIR"
chmod 700 "$AGE_DIR"

if [ ! -f "$AGE_DIR/key.txt" ]; then
    age-keygen -o "$AGE_DIR/key.txt"

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

Natural-language instructions and descriptions throughout the file are presented only in Spanish. Under the stated policy, forcing a specific language without user opt-in or justification is a locale-policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The natural-language comments and usage description are written only in Spanish, which can violate language/locale policy when no user opt-in or justification is provided. The file does not indicate that the skill is intentionally region- or language-specific.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.