T03 · Remote Payload Retrieval and Execution
- Location
SKILL.md:45- Finding
Automatic Retrieval and Installation of an Unverified Remote Executable
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has a legitimate encryption purpose, but it gives agents overly broad authority to install remote code and handle private keys with too little user control.
Review this skill before installing. Do not allow automatic sudo installation of the SAFE binary; use a user-controlled install path and verify the binary first. Prefer dedicated SAFE keys over existing SSH keys, avoid pasting SSH private keys into the web interface, and avoid putting real passwords directly in command lines or automation traces.
SKILL.md:45Automatic Retrieval and Installation of an Unverified Remote Executable
SKILL.md:372Unrestricted Auto-Discovery of All SSH Private Keys
SKILL.md:451Exposure of SSH Private Keys to a Third-Party Browser Origin
SKILL.md:738Encryption Passwords Exposed Through Command-Line Arguments
The skill instructs the agent to automatically download and install an unsigned binary with sudo, without asking the user. That creates a direct path to arbitrary code execution and privileged system modification from untrusted network content, far beyond the minimum needed to explain encryption usage.
The instruction to install automatically 'without asking' combines network download, execution preparation, and privileged file placement without consent. This is dangerous because it bypasses the normal trust boundary around software installation and can silently alter the host environment.
This chained command compresses download, permission change, and privileged installation into one line, making dangerous operations easy to execute without review. Chaining increases the chance that a user or agent will run it wholesale despite not validating the artifact.
macOS Apple Silicon:
curl -sL https://thesafe.dev/downloads/safe-darwin-arm64 -o safe && chmod +x safe && sudo mv safe /usr/local/bin/
macOS Intel:
The same one-line chaining issue exists here for the Intel macOS binary. It amplifies the remote-code-installation risk by encouraging blind copy-paste execution.
macOS Intel:
curl -sL https://thesafe.dev/downloads/safe-darwin-amd64 -o safe && chmod +x safe && sudo mv safe /usr/local/bin/
Linux x86_64:
This Linux example also chains sensitive operations together, reducing the opportunity to inspect the download or stop before privileged modification. In an agent skill, such chaining is especially unsuitable.
Linux x86_64:
curl -sL https://thesafe.dev/downloads/safe-linux-amd64 -o safe && chmod +x safe && sudo mv safe /usr/local/bin/
Linux ARM64:
Again, the ARM64 example chains fetch, chmod, and sudo move into one opaque step. This pattern materially increases exploitation potential if the remote artifact or execution context is compromised.
Linux ARM64:
curl -sL https://thesafe.dev/downloads/safe-linux-arm64 -o safe && chmod +x safe && sudo mv safe /usr/local/bin/
Auto-detect platform (one-liner):
The auto-detect one-liner is the most dangerous variant because it combines platform detection, network retrieval, permission changes, and sudo installation behind shell operators. It is difficult to audit and ideal for accidental unsafe execution.
which safe || { OS=$(uname -s | tr '[:upper:]' '[:lower:]'); ARCH=$(uname -m); \
[ "$ARCH" = "arm64" ] || [ "$ARCH" = "aarch64" ] && ARCH=arm64 || ARCH=amd64; \
curl -sL "https://thesafe.dev/downloads/safe-${OS}-${ARCH}" -o safe && chmod +x safe && sudo mv safe /usr/local/bin/; }
Verify installation:
Automatically saving generated keys in a browser keychain and reusing them across operations expands secret retention in a web context. That increases exposure to browser compromise, unintended persistence, and automated handling of private keys beyond the user’s immediate task.
1. **Encrypt**: Enter plaintext, add recipients (key, password, passkey, or GitHub username), click "ENCRYPT". Copy or download the output.
2. **Decrypt**: Paste/upload/URL-load a SAFE message, add credentials (private key, password, passkey, or GitHub), click "DECRYPT". Copy or download the plaintext.
Generated keys are automatically saved in the KEYCHAIN section and can be reused across operations.
**Agent with MCP browser tools (Playwright, Puppeteer, etc.):**
The UI guidance encourages adding all keychain entries as credentials in a decryption attempt, which can cause unnecessary use of stored secrets and broaden the blast radius if automation is compromised or over-collects keys. It normalizes bulk secret handling rather than least-privilege credential use.
| Encrypted output | "Encrypted SAFE message output" | textbox |
| SAFE message input | "Paste encrypted SAFE message to decrypt" | textbox |
| Add credential button (decrypt) | "Add credential to decryption attempt" | button |
| Add credential button (keychain) | "Add credential to keychain" | button |
| Add all keychain button | "Add all keychain entries as credentials" | button |
| Credential type selector | "Select credential type" | combobox |
| New Passkey menu item | "Create a new passkey" | menuitem |
A browser feature that shows or copies private keys materially increases the chance of secret disclosure through clipboard managers, browser automation logs, screenshots, or accidental paste. In a security skill, exposing raw private keys through convenience actions is dangerous.
- **PRIV**: Shows/copies the private key
- **Share**: Generates a shareable URL for the public key
- **Label**: Rename the key for easier identification
- **Del**: Removes the key from the keychain
**Prefer using Enc/Dec shortcuts** over the manual Add Step flow when keys are saved in the keychain — it reduces 4 interactions to 1.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- **Label**: Rename the key for easier identification
- **Del**: Removes the key from the keychain
**Prefer using Enc/Dec shortcuts** over the manual Add Step flow when keys are saved in the keychain — it reduces 4 interactions to 1.
**File upload:**
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Example Auto-Discovery Output:
$ curl -sL https://gist.github.com/.../raw | safe decrypt
safe: using SSH key ~/.ssh/id_ed25519
safe: trying 3 key(s) (2 native + 1 SSH)
[decrypted message]
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Example Auto-Discovery Output:
$ curl -sL https://gist.github.com/.../raw | safe decrypt
safe: using SSH key ~/.ssh/id_ed25519
safe: trying 3 key(s) (2 native + 1 SSH)
[decrypted message]
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Example Auto-Discovery Output:
$ curl -sL https://gist.github.com/.../raw | safe decrypt
safe: using SSH key ~/.ssh/id_ed25519
safe: trying 3 key(s) (2 native + 1 SSH)
[decrypted message]
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Example Auto-Discovery Output:
$ curl -sL https://gist.github.com/.../raw | safe decrypt
safe: using SSH key ~/.ssh/id_ed25519
safe: trying 3 key(s) (2 native + 1 SSH)
[decrypted message]
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Example Auto-Discovery Output:
$ curl -sL https://gist.github.com/.../raw | safe decrypt
safe: using SSH key ~/.ssh/id_ed25519
safe: trying 3 key(s) (2 native + 1 SSH)
[decrypted message]
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# Option 1: Use existing SSH keys (simplest - zero setup!)
# If you already have ~/.ssh/id_ed25519 or ~/.ssh/id_ecdsa uploaded to GitHub, you're done!
# SAFE CLI auto-discovers SSH keys - no key generation needed
# Option 2: Generate new SSH key and upload to GitHub
This same instruction references a second SSH private key type and carries the same risk: it normalizes disclosure of sensitive private-key material to a browser application. Reuse of existing SSH keys for browser decryption can compromise unrelated authentication domains if mishandled.
2. Load the encrypted message: paste text, use the **FILE** button to upload, or use the **URL** button to load directly from a Gist URL (e.g., paste the raw Gist URL)
3. Click **ADD** → **GITHUB** → enter your GitHub username → click **FETCH KEYS**
(This matches your public keys to the message's LOCK blocks)
4. Click **ADD** → **KEY** → paste your SSH private key (from `~/.ssh/id_ed25519` or `~/.ssh/id_ecdsa`)
— or use the **"Import SSH private key from GitHub"** button if available
5. Click **DECRYPT**
This same instruction references a second SSH private key type and carries the same risk: it normalizes disclosure of sensitive private-key material to a browser application. Reuse of existing SSH keys for browser decryption can compromise unrelated authentication domains if mishandled.
2. Load the encrypted message: paste text, use the **FILE** button to upload, or use the **URL** button to load directly from a Gist URL (e.g., paste the raw Gist URL)
3. Click **ADD** → **GITHUB** → enter your GitHub username → click **FETCH KEYS**
(This matches your public keys to the message's LOCK blocks)
4. Click **ADD** → **KEY** → paste your SSH private key (from `~/.ssh/id_ed25519` or `~/.ssh/id_ecdsa`)
— or use the **"Import SSH private key from GitHub"** button if available
5. Click **DECRYPT**
Exporting a browser keychain as a file containing private keys, even if encrypted, creates a concentrated high-value secret artifact. This raises theft and persistence risks, especially when paired with automation and generic storage recommendations.
- **New Passkey**: Create a new WebAuthn passkey (requires browser/OS authenticator, prompts for label)
- **New Password**: Add a new password for encryption/decryption
- **Existing Passkey**: Use an existing passkey from your authenticator
- **Export**: Export keychain as encrypted SAFE backup (password-protected `.safe` file containing private keys in PEM format)
- **Import**: Import a previously exported keychain backup (file upload + passphrase)
- **Clear All**: Delete all keychain entries (shows a confirm dialog)
Importing encrypted keychain backups into browser workflows expands the number of contexts where private keys may be exposed in memory, logs, or automation traces. It also encourages transportable private-key bundles that are attractive attack targets.
- **New Password**: Add a new password for encryption/decryption
- **Existing Passkey**: Use an existing passkey from your authenticator
- **Export**: Export keychain as encrypted SAFE backup (password-protected `.safe` file containing private keys in PEM format)
- **Import**: Import a previously exported keychain backup (file upload + passphrase)
- **Clear All**: Delete all keychain entries (shows a confirm dialog)
**Passkey Limitations for Automation:**
Promoting persistent browser identity through saved keychain backups encourages long-lived secret retention across sessions and systems. That increases compromise surface and departs from safer ephemeral-browser assumptions.
### Agent Session Persistence (Browser Workflow)
Agents can maintain a persistent identity across browser sessions by saving and re-uploading the keychain backup:
**First browser session**:
1. Navigate to https://thesafe.dev
This line specifically recommends exporting the keychain to an encrypted backup file for later reuse, meaning private keys are being externalized into a portable secret package. If mishandled or weakly protected, compromise of that file compromises all contained identities.
**First browser session**:
1. Navigate to https://thesafe.dev
2. Generate keys (Section 01) or receive keys from other agents
3. Export keychain: Click "Export" → enter passphrase → download `safe-credentials-backup.safe`
4. Save the encrypted backup file to persistent storage (filesystem, database, cloud storage, etc.)
5. Store the passphrase securely (environment variable, secure key store, etc.)
Automation examples that click 'Export keychain' encourage scripted handling of private-key backups, increasing the risk of unattended export, accidental retention, and insecure storage. Secret-export operations should not be normalized in default automation examples.
Example workflow with MCP Playwright:
# First session: Export keychain
browser_click(ref=<export-button-ref>) # "Export keychain"
# Enter passphrase in dialog
browser_type(ref=<passphrase-ref>, text="agent-secret-passphrase")
Typing backup passphrases into automated browser flows increases exposure through automation traces, screenshots, process memory, and logging. Combined with key export, this compounds the risk around private-key portability.
# First session: Export keychain
browser_click(ref=<export-button-ref>) # "Export keychain"
# Enter passphrase in dialog
browser_type(ref=<passphrase-ref>, text="agent-secret-passphrase")
browser_type(ref=<confirm-passphrase-ref>, text="agent-secret-passphrase")
No suspicious patterns detected.