Back to skill

Security audit

Flomo Send

Security checks for vulnerabilities and agentic risk

Overview

This skill does send notes to flomo, but its instructions and scripts create review-worthy risk around always-network delivery, persistent token storage, and unsafe shell configuration handling.

Review before installing. Use only webhook values copied directly from flomo, avoid choosing the shell startup file option, and inspect or harden the scripts before use. The package should validate and safely serialize tokens, parse configuration as data instead of sourcing .env, and align SKILL.md with the webhook-only implementation.

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
scripts/configure.sh:82
Finding

Arbitrary Command Execution Through Unsafely Persisted Webhook Input

Content
View full analysis

Vulnerability Details

File Location: scripts/configure.sh:33-50, scripts/configure.sh:76-98, and scripts/flomo_send.sh:13-19
Vulnerability Type: Shell command injection through executable configuration files
Risk Level: High

The configuration script accepts webhook input and writes it directly into either a local .env file or a shell startup file without validation or shell-safe serialization. The send script subsequently executes the .env file using source.

Vulnerable Code

User-controlled webhook input is collected without restricting shell metacharacters:

bash
read -rp "Webhook token (or full URL): " WEBHOOK_INPUT

if [ -z "$WEBHOOK_INPUT" ]; then
    echo "⚠️  No webhook provided. You can configure it later by running this script again."
    exit 0
fi

# Detect if user pasted full URL or just token
if echo "$WEBHOOK_INPUT" | grep -q "^https://flomoapp.com/iwh/"; then
    # Full URL provided
    WEBHOOK_URL="$WEBHOOK_INPUT"
    WEBHOOK_TOKEN=$(echo "$WEBHOOK_URL" | sed 's|https://flomoapp.com/iwh/||')
    echo ""
    echo "✅ Webhook URL configured"
else
    # Just token provided
    WEBHOOK_TOKEN="$WEBHOOK_INPUT"
    WEBHOOK_URL="https://flomoapp.com/iwh/$WEBHOOK_TOKEN"
    echo ""
    echo "✅ Webhook token configured"
fi

The resulting value is embedded directly into executable shell syntax:

bash
case "$CONFIG_CHOICE" in
    2)
        # Save to shell config
        if [ -n "$SHELL_CONFIG" ]; then
            echo "" >> "$SHELL_CONFIG"
            echo "# Flomo Skill Configuration" >> "$SHELL_CONFIG"
            echo "export FLOMO_WEBHOOK_TOKEN=$WEBHOOK_TOKEN" >> "$SHELL_CONFIG"
            echo ""
            echo "✅ Configuration saved to: $SHELL_CONFIG"
            echo "   Please run: source $SHELL_CONFIG"
        else
            echo "⚠️  Could not detect shell config file."
            echo "   Please manually add to your s
...[truncated 3689 chars]
Remediation
View remediation

Remediation Suggestions

  1. Apply strict token validation. If the user provides only a webhook token, permit only the characters required by the service. For example:

    bash
    if [[ ! "$WEBHOOK_INPUT" =~ ^[A-Za-z0-9_-]+$ ]]; then
        echo "Error: Invalid webhook token format" >&2
        exit 1
    fi
    

    The precise allowlist should be aligned with flomo's documented token format.

  2. Validate full URLs structurally. Require:

    • The https scheme.
    • The exact expected flomo hostname.
    • The expected /iwh/ path.
    • A token segment that satisfies the strict token allowlist.
    • No username, password, fragment, unexpected port, query parameters, whitespace, control characters, or shell metacharacters.
  3. Do not source .env as executable code. Treat the configuration as data and parse only explicitly supported keys. A safer design is to store only the raw token in a dedicated file and read it with a non-evaluating operation:

    bash
    IFS= read -r FLOMO_WEBHOOK_TOKEN < "$TOKEN_FILE"
    export FLOMO_WEBHOOK_TOKEN
    
  4. Avoid writing secrets into shell startup files. Prefer a dedicated configuration file with mode 600. Shell startup files increase both command-execution exposure and persistence risk.

  5. If shell output is retained, serialize defensively. Validate the value first and then use a shell-aware escaping mechanism such as printf '%q' rather than string interpolation:

    bash
    printf 'export FLOMO_WEBHOOK_TOKEN=%q\n' "$WEBHOOK_TOKEN" >> "$SHELL_CONFIG"
    

    Escaping should be defense in depth and must not replace strict validation.

  6. Reject dangerous input explicitly. Reject whitespace, control characters, command substitutions, backticks, quotes, semicolons, redirection operators, backslashes, and line breaks.

  7. Add regression tests. Test values containing command substitutions, semicolons, quotes, backticks, space ...[truncated 186 chars]

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (36)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented behavior claims primary local delivery via flomo URL Scheme with automatic webhook fallback, but the analysis indicates the implementation only uses webhook delivery and lacks app invocation or fallback logic. This mismatch is security-relevant because users may expose webhook secrets or trust local-only behavior when the skill actually transmits data over the network, causing unintended disclosure of note contents and tokens.

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 30)May include surrounding context.

md
scripts/flomo_send.sh "Your note content" "#tag1 #tag2"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
scripts/flomo_send.sh "Your note content" "#tag1 #tag2"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
scripts/flomo_send.sh "Your note content" "#tag1 #tag2"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
scripts/flomo_send.sh "Your note content" "#tag1 #tag2"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
scripts/flomo_send.sh "Your note content" "#tag1 #tag2"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
scripts/flomo_send.sh "Your note content" "#tag1 #tag2"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
scripts/flomo_send.sh "Your note content" "#tag1 #tag2"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
scripts/flomo_send.sh "Your note content" "#tag1 #tag2"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
scripts/flomo_send.sh "Your note content" "#tag1 #tag2"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
scripts/flomo_send.sh "Your note content" "#tag1 #tag2"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
scripts/flomo_send.sh "Your note content" "#tag1 #tag2"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
scripts/flomo_send.sh "Your note content" "#tag1 #tag2"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
scripts/flomo_send.sh "Your note content" "#tag1 #tag2"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
scripts/flomo_send.sh "Your note content" "#tag1 #tag2"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/configure.sh (reported line 69)May include surrounding context.

sh
echo ""
        echo "Where would you like to save the configuration?"
        echo "1) Create a local .env file in skill directory (default - recommended)"
        echo "2) Shell config file ($SHELL_CONFIG)"
        read -rp "Choice [1-2] (default: 1): " CONFIG_CHOICE

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/configure.sh (reported line 101)May include surrounding context.

sh
echo ""
        echo "Where would you like to save the configuration?"
        echo "1) Create a local .env file in skill directory (default - recommended)"
        echo "2) Shell config file ($SHELL_CONFIG)"
        read -rp "Choice [1-2] (default: 1): " CONFIG_CHOICE

Credential Access

High
Category
Privilege Escalation
Confidence
85% confidence
Finding

The script stores a sensitive webhook token in a plaintext .env file inside the skill directory. Although permissions are later restricted, plaintext secret storage in a project directory can lead to accidental disclosure through backups, indexing, misconfigured sharing, or source-control commits if the file is not excluded.

Content

Scanner excerpt · scripts/configure.sh (reported line 93)May include surrounding context.

sh
fi
                ;;
            *)
                # Save to .env file (default)
                ENV_FILE="$(dirname "$0")/../.env"
                echo "# Flomo Skill Configuration" > "$ENV_FILE"
                echo "FLOMO_WEBHOOK_TOKEN=$WEBHOOK_TOKEN" >> "$ENV_FILE"

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

This line writes FLOMO_WEBHOOK_TOKEN directly to a plaintext .env file, creating a local secret-at-rest exposure. Anyone who gains access to the user's account, the repository contents, or synced files may be able to reuse the webhook to send content to the user's flomo inbox.

Content

Scanner excerpt · scripts/configure.sh (reported line 94)May include surrounding context.

sh
;;
            *)
                # Save to .env file (default)
                ENV_FILE="$(dirname "$0")/../.env"
                echo "# Flomo Skill Configuration" > "$ENV_FILE"
                echo "FLOMO_WEBHOOK_TOKEN=$WEBHOOK_TOKEN" >> "$ENV_FILE"
                echo "# FLOMO_WEBHOOK_URL=$WEBHOOK_URL" >> "$ENV_FILE"

Credential Access

High
Category
Privilege Escalation
Confidence
78% confidence
Finding

The script automatically sources a local .env file and exports all variables into the process environment. Because source executes shell syntax rather than just parsing key/value pairs, a maliciously modified .env could run arbitrary shell commands when the script starts, making this a code-execution risk rather than merely credential loading.

Content

Scanner excerpt · scripts/flomo_send.sh (reported line 13)May include surrounding context.

sh
set -e

# Load local .env if present (export variables so they're available to curl/python)
ENV_FILE="$(dirname "$0")/../.env"
if [ -f "$ENV_FILE" ]; then
    set -o allexport

Credential Access

High
Category
Privilege Escalation
Confidence
78% confidence
Finding

This finding points to the same unsafe .env-loading behavior: a nearby untrusted configuration file is executed via shell sourcing. In a skill context where users are instructed to run setup scripts and keep webhook secrets locally, this increases the chance that a tampered repository or local file could execute attacker-controlled code and expose credentials or alter the webhook destination.

Content

Scanner excerpt · scripts/flomo_send.sh (reported line 14)May include surrounding context.

sh
set -e

# Load local .env if present (export variables so they're available to curl/python)
ENV_FILE="$(dirname "$0")/../.env"
if [ -f "$ENV_FILE" ]; then
    set -o allexport
    # shellcheck disable=SC1090

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The README instructs users to send note content through a webhook but does not clearly warn that potentially sensitive user notes will be transmitted over the network to a third-party service endpoint. In a note-capture skill, users may paste clipboard contents, ideas, links, or other private material, so missing privacy disclosure increases the risk of unintended sensitive-data exposure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest says this skill sends to flomo via URL Scheme with automatic webhook fallback and supports quick capture workflows on macOS. However, the README explicitly states that URL Scheme mode was canceled/removed and that the skill now uniformly uses the Webhook API, creating a direct documentation-versus-stated-intent contradiction.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest presents the skill as using URL Scheme with automatic fallback to webhook if the app is unavailable. In contrast, the README states that URL Scheme direct invocation has been removed and users must use the Webhook API, indicating the actual documented behavior is broader/different than the manifest description.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill documents shell-based execution (./scripts/configure.sh, ./scripts/flomo_send.sh) but does not declare any tool scope such as permissions or allowed-tools. This creates an authorization gap where an agent or reviewer cannot clearly determine what command execution is expected, increasing the risk of unintended shell access and unsafe execution of bundled scripts.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.