T09 · Insecure Skill Coding Practices
- Location
SKILL.md:23- Finding
Unauthenticated Decrypted Content Is Executed as Shell Code
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:23andscripts/secure/setup.sh:54-56
Vulnerability Type: Execution of unauthenticated decrypted content
Risk Level: HighThe documented workflow recommends decrypting an
.agefile 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
sourcecommand interprets every statement in the decrypted file as shell code within the caller's current shell. The workflow assumes that successfulagedecryption establishes that the plaintext was authored by a trusted party.Recipient-based
ageencryption 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 inscripts/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
- The attacker obtains the recipient public key, which the setup script displays and recommends sharing.
- The attacker creates plaintext containing arbitrary shell commands, potentially mixed with plausible environment-variable assignments.
- The attacker encrypts that payload to the victim's public key using
age. - The a ...[truncated 1373 chars]
- Remediation
View remediation
Remediation Suggestions
-
Do not source decrypted content directly. Remove all recommendations that pipe decrypted output into
source,eval, or another command interpreter. -
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.
-
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.
-
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. -
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.
-
Harden repository and artifact controls. Require review and signature verification for changes to encrypted secret artifacts so unauthorized replacements are detected before use.
-
Make key-path behavior consistent. The checked-in helper scripts use
/root/.age/key.txt, while the versions generated bysetup.shuse$HOME/.age/key.txt. Standardize the path and avoid implying that root execution is required.
-
