Back to skill

Security audit

Raindrop.io Bookmarks

Security checks for vulnerabilities and agentic risk

Overview

This looks like a real Raindrop.io bookmark tool, but its credential handling and immediate write/delete operations create risks that users should review before installing.

Install only if you are comfortable giving this skill read/write access to your Raindrop.io account, including deletion and bulk movement of bookmarks. Before regular use, prefer a secure credential store or protected environment variable, avoid passing tokens on the command line, restrict any token file permissions, and consider fixing the script to parse the token file as data, validate --delay, and require explicit confirmation for delete and bulk operations.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/raindrop.sh:11
Finding

Arbitrary Shell Execution Through Executable Credential Configuration

Content
View full analysis

Vulnerability Details

File Location: scripts/raindrop.sh, lines 11-13
Vulnerability Type: Unsafe execution of a credential configuration file
Risk Level: High

bash
# Auto-source token from config if not set
if [[ -z "$TOKEN" && -f ~/.config/raindrop.env ]]; then
  source ~/.config/raindrop.env
fi

Technical Analysis

The script loads ~/.config/raindrop.env with the Bash source builtin. Although this file is documented as a credential file, source interprets its entire contents as executable shell code rather than parsing it strictly as data.

Consequently, any command, command substitution, function definition, shell redirection, or other Bash construct placed in the file will execute when the CLI starts without an existing RAINDROP_TOKEN environment variable. Merely checking that the file exists does not validate its ownership, permissions, type, or contents.

Attack Path

  1. An attacker, compromised process, or malicious installation step gains the ability to create or modify ~/.config/raindrop.env.
  2. The attacker inserts shell commands into the file, for example alongside or instead of the expected token assignment.
  3. The user invokes any command in scripts/raindrop.sh without setting RAINDROP_TOKEN.
  4. The startup logic executes source ~/.config/raindrop.env.
  5. The attacker-controlled commands execute before the requested Raindrop operation.

Impact Assessment

Successful exploitation provides arbitrary command execution with the privileges of the user or Agent running the Skill. This may permit access to local files and environment secrets, modification or deletion of user data, use of the Raindrop token, network access under the user's identity, and further compromise within that account's permission boundary.

Remediation
View remediation

Remediation Suggestions

Do not execute credential files with source. Replace this behavior with a non-executing parser that accepts only a single, precisely defined RAINDROP_TOKEN assignment.

Recommended hardening includes:

  1. Read the file as plain text rather than Bash code.
  2. Reject unknown keys, multiline values, command substitutions, and additional statements.
  3. Confirm that the path is a regular file and not a symbolic link.
  4. Verify that the file is owned by the current user and is not accessible by group or other users.
  5. Require mode 0600 for the file and mode 0700 for its containing directory.
  6. Prefer an operating-system credential store or an inherited environment variable where available.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/raindrop.sh:88
Finding

Command Injection Through Unvalidated Delay Arithmetic

Content
View full analysis

Vulnerability Details

File Location: scripts/raindrop.sh, lines 88-103
Vulnerability Type: Shell arithmetic and expression injection
Risk Level: High

bash
# Rate limiting helper
rate_limit() {
  if [[ "$DELAY" -gt 0 ]]; then
    sleep "$(echo "scale=3; $DELAY/1000" | bc)"
  fi
}

LIMIT=25
PAGE=0
POSITIONAL=()
UPDATE_TAGS=""
UPDATE_TITLE=""
UPDATE_COLLECTION=""

while [[ $# -gt 0 ]]; do
  case "$1" in
    --token) TOKEN="$2"; shift 2 ;;
    --json) FORMAT="json"; shift ;;
    --limit) LIMIT="$2"; shift 2 ;;
    --delay) DELAY="$2"; shift 2 ;;

Technical Analysis

The --delay argument is copied directly into DELAY without numeric validation. It is subsequently processed as a Bash arithmetic expression by:

bash
[[ "$DELAY" -gt 0 ]]

Bash arithmetic evaluation can recursively resolve variable and array expressions, making attacker-controlled arithmetic expressions unsafe. The same value is also interpolated directly into an expression passed to bc:

bash
echo "scale=3; $DELAY/1000" | bc

This creates multiple expression-evaluation surfaces. The script already defines is_uint, but it does not apply that validation to DELAY.

Attack Path

  1. An attacker controls or influences arguments supplied to the Skill.
  2. The attacker provides a crafted nonnumeric value through --delay.
  3. The user or Agent requests any operation that calls api.
  4. api invokes rate_limit.
  5. Bash evaluates the attacker-controlled value in arithmetic context.
  6. A crafted arithmetic expression can trigger unintended shell evaluation and execute commands with the caller's privileges.

Impact Assessment

Exploitation can result in arbitrary local command execution as the account running the Skill. The attacker may read Agent-accessible secrets, modify local files, steal the Raindrop token, perform authenticated API operations, or invoke other prog ...[truncated 31 chars]

Remediation
View remediation

Remediation Suggestions

Validate --delay immediately when parsing it and before any arithmetic evaluation:

bash
--delay)
  [[ $# -ge 2 ]] || die "--delay requires a value"
  is_uint "$2" || die "--delay must be an unsigned integer"
  (( 10#$2 <= 60000 )) || die "--delay exceeds the maximum value"
  DELAY="$2"
  shift 2
  ;;

Additional hardening should include:

  1. Enforce a reasonable upper bound to prevent excessive sleeping or denial of service.
  2. Avoid bc for this conversion.
  3. Convert validated integer milliseconds using controlled integer formatting.
  4. Validate that every option requiring a value has a following argument before reading $2.
  5. Add tests using malformed arithmetic expressions, negative values, very large values, and missing arguments.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/raindrop.sh:102
Finding

API Token Exposure Through Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: scripts/raindrop.sh, line 102; documented in SKILL.md, lines 31-32
Vulnerability Type: Sensitive credential exposure through process arguments and shell history
Risk Level: Medium

bash
# Or pass token at runtime (recommended for ephemeral use)
{baseDir}/scripts/raindrop.sh --token "your-token" whoami
bash
while [[ $# -gt 0 ]]; do
  case "$1" in
    --token) TOKEN="$2"; shift 2 ;;

Technical Analysis

The CLI accepts the Raindrop API token directly through --token, and the documentation recommends this mechanism for ephemeral use. Command-line arguments may be recorded in shell history, terminal logs, automation logs, process-monitoring systems, diagnostic output, or process listings available to other local principals, depending on the operating system and environment.

Removing the argument from the script's positional parameters after startup does not retroactively remove it from shell history and may not remove it from operating-system process metadata.

Attack Path

  1. A user follows the documented example and supplies a live API token using --token.
  2. The complete command is retained in shell history, logs, or process metadata.
  3. Another local user, support process, monitoring service, or compromised application reads that information.
  4. The exposed bearer token is used directly against the Raindrop API.
  5. The attacker performs operations authorized by that token.

Impact Assessment

The exposed token can grant unauthorized access to the victim's Raindrop account within the token's scope. Because this Skill supports both reading and writing, potential consequences include disclosure of private bookmark titles, URLs, tags, notes, collections, and account information, as well as creation, modification, movement, or deletion of bookmarks.

Remediation
View remediation

Remediation Suggestions

Remove or strongly discourage the --token option. Prefer, in order:

  1. An operating-system credential manager or secret store.
  2. A protected credential file parsed strictly as data.
  3. An inherited environment variable set through a secure execution environment.
  4. Silent interactive input using read -r -s when appropriate.

Update SKILL.md so that it does not recommend placing a token directly in a command. If backward compatibility requires retaining --token, display a warning and document that the value may be exposed through history, logs, and process inspection.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:27
Finding

Credential File Created Without Explicit Restrictive Permissions

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 27-29
Vulnerability Type: Insecure storage instructions for an API credential
Risk Level: Medium

bash
# Get token from: https://app.raindrop.io/settings/integrations → "Create test token"
echo 'RAINDROP_TOKEN="your-token"' > ~/.config/raindrop.env

Technical Analysis

The setup instructions write the API token to a plaintext file using shell redirection without explicitly setting secure permissions. The resulting access mode depends on the user's current umask and the state of any existing file. The instructions also do not verify the ownership or type of ~/.config/raindrop.env.

On a system with a permissive umask, the file may be readable by other local users. If the destination already exists with broad permissions, redirecting new content into it generally preserves those permissions. A pre-existing symbolic link can also redirect the credential write to another location accessible to the user.

Attack Path

  1. The user follows the documented setup command.
  2. The user's umask is permissive, the destination already has insecure permissions, or the path has been replaced with an unsafe file type.
  3. The token is written in plaintext without a mode or ownership check.
  4. Another local principal or process reads the file.
  5. The attacker uses the bearer token to access the victim's Raindrop account.

Impact Assessment

Exposure affects the Raindrop account and all data or operations authorized by the token. An attacker may inspect private bookmark data and perform write operations such as adding, updating, moving, or deleting bookmarks. This issue does not independently grant privileges beyond those of the stolen token.

Remediation
View remediation

Remediation Suggestions

Replace the setup instructions with a procedure that creates both the directory and credential file using explicit restrictive permissions:

bash
install -d -m 700 "$HOME/.config"
install -m 600 /dev/null "$HOME/.config/raindrop.env"

The token should then be collected without embedding it in command history and written only after validating that the destination is a regular file owned by the current user. The script should refuse to load credential files that are symbolic links, have unexpected ownership, or are accessible by group or other users. An operating-system credential store is preferable to a plaintext file.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (11)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

The delete path accepts a user-supplied bookmark ID and directly performs a remote DELETE request, enabling tool parameter abuse if an upstream agent, prompt, or user input is wrong or manipulated. Because this tool has write/delete capabilities against a live account, the skill context makes unrestricted parameterized deletion materially riskier than a read-only integration.

Content

Scanner excerpt · scripts/raindrop.sh (reported line 213)May include surrounding context.

sh
[[ -z "${1:-}" ]] && die "Bookmark ID required"
    id="$1"
    is_uint "$id" || die "Bookmark ID must be an unsigned integer"
    api DELETE "/raindrop/$id" | if [[ "$FORMAT" == "json" ]]; then cat; else jq -r 'if .result then "Deleted" else "Failed" end'; fi
    ;;
  
  move)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill clearly relies on shell execution and outbound network access to the Raindrop API, but it does not declare any explicit tool scope or allowed tools. In an agent environment, missing capability declarations weakens policy enforcement and makes it easier for the skill to be invoked with broader-than-expected privileges.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The setup instructions encourage storing an API token in a persistent plaintext file under the user's home directory. Long-lived local credential persistence increases exposure to token theft by other processes, accidental inclusion in backups, or misuse by later sessions beyond the user's original intent.

Content

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

Setup

bash
# Get token from: https://app.raindrop.io/settings/integrations → "Create test token"
echo 'RAINDROP_TOKEN="your-token"' > ~/.config/raindrop.env

# Or pass token at runtime (recommended for ephemeral use)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill documents a destructive delete command without warning about confirmation, reversibility, or the risk of accidental data loss. In an agent-assisted workflow, this increases the chance that a user or model triggers permanent or hard-to-recover bookmark deletion unintentionally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Bulk move and update operations can modify many bookmarks at once, but the skill does not present a clear user-facing warning about blast radius, validation, or confirmation. This makes accidental large-scale reorganization or corruption of bookmark metadata more likely when invoked by an agent.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
source ~/.config/raindrop.env

# Update tags
curl -X PUT "https://api.raindrop.io/rest/v1/raindrop/ID" \
  -H "Authorization: Bearer $RAINDROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tags": ["tag1", "tag2"]}'

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
set -euo pipefail

API="https://api.raindrop.io/rest/v1"
TOKEN="${RAINDROP_TOKEN:-}"
FORMAT="pretty"  # pretty or json
DELAY=0  # ms delay between requests for rate limiting

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
set -euo pipefail

API="https://api.raindrop.io/rest/v1"
TOKEN="${RAINDROP_TOKEN:-}"
FORMAT="pretty"  # pretty or json
DELAY=0  # ms delay between requests for rate limiting

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/raindrop.sh (reported line 7)May include surrounding context.

sh
set -euo pipefail

API="https://api.raindrop.io/rest/v1"
TOKEN="${RAINDROP_TOKEN:-}"
FORMAT="pretty"  # pretty or json
DELAY=0  # ms delay between requests for rate limiting

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script exposes a destructive delete operation that executes immediately with no confirmation prompt, dry-run mode, or undo guidance. In an agent/tooling context, this increases the chance of accidental or prompt-induced deletion of user bookmarks because a single mistaken invocation irreversibly changes remote state.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The script silently sources ~/.config/raindrop.env when no token is provided, causing credential use from local disk without explicit user awareness at runtime. In an agent setting, this can lead to unintended access to a user's Raindrop account and unexpected external actions under their identity.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.