Back to skill

Security audit

Dnote

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Dnote note-management helper, but it includes unsafe install guidance and wrapper behavior that can delete, sync, or expose user data with limited guardrails.

Review this skill before installing. Prefer Homebrew or a pinned, verified Dnote release instead of the pipe-to-shell installer; avoid storing secrets in notes; only run sync after deciding remote upload is acceptable; require explicit confirmation before delete commands; and avoid using `config` unless you are comfortable exposing the config file contents to the agent session.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:24
Finding

Unverified Remote Installer Is Executed Directly by a Shell

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:24
Vulnerability Type: Remote payload retrieval and execution
Risk Level: High

Vulnerable Code

bash
curl -s https://www.getdnote.com/install | sh

Technical Analysis

The installation instructions pipe a response obtained from an external URL directly into sh. The downloaded content is neither pinned to an immutable version nor verified using a cryptographic checksum or signature before execution.

Although the URL uses HTTPS and appears related to the declared Dnote functionality, the effective code can change after the Skill has been reviewed. A compromise of the remote server, deployment pipeline, domain, or relevant trust infrastructure could therefore replace the installer with arbitrary shell commands.

Direct execution is not required for the Skill's note-management functionality. The document already identifies Homebrew and downloadable GitHub releases as alternative installation methods that can support safer, reviewable installation.

Attack Path

  1. A user or agent follows the installation instructions.
  2. curl retrieves the current response from the external installer endpoint.
  3. The response is passed directly to sh without being stored, reviewed, pinned, or integrity-checked.
  4. Any commands present in the response execute immediately.
  5. A compromised or malicious response can read or alter files, install additional software, access credentials available to the process, or establish persistence.

Impact Assessment

Exploited code runs with the privileges of the user invoking the command. It can access that user's files, environment variables, credentials, network permissions, and writable configuration or executable paths. If the command is invoked from a privileged account or elevated environment, the impact expands to those privileges. The packaged instruction does not itself request privilege elevation.

Remediation
View remediation

Remediation Suggestions

  • Remove the curl | sh installation method.
  • Prefer a trusted package manager such as Homebrew where appropriate.
  • Alternatively, download a release pinned to a specific version from the official release repository.
  • Verify the artifact with a publisher-provided cryptographic checksum or signature before execution.
  • Store and inspect installation scripts before running them rather than streaming them directly into a shell.
  • Document that installation should occur as an unprivileged user and should not use sudo unless a specific operation demonstrably requires it.
  • Use fail-safe download options such as curl --fail --show-error --location so HTTP errors are not silently treated as executable input.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/dnote.sh:164
Finding

Unvalidated Recent-Count Argument Reaches Bash Arithmetic Evaluation

Content
View full analysis

Vulnerability Details

File Location: scripts/dnote.sh:164-186
Vulnerability Type: Bash arithmetic injection
Risk Level: High

Vulnerable Code

bash
cmd_recent() {
  local n="${1:-10}"

  # Get all notes sorted by time (most recent first)
  # This is a simplified version - dnote doesn't have a native "recent" command
  # We iterate through books and show recent entries
  local books
  books=$($DNODE_CMD view --name-only 2>/dev/null | head -50)

  echo "Recent notes (last $n):"
  echo "======================="

  local count=0
  while IFS= read -r book && [[ $count -lt $n ]]; do
    [[ -z "$book" ]] && continue
    local notes
    notes=$($DNODE_CMD view "$book" 2>/dev/null | head -5) || continue
    if [[ -n "$notes" ]]; then
      echo ""
      echo "[$book]"
      echo "$notes" | head -$((n - count))
      count=$((count + $(echo "$notes" | wc -l)))
    fi
  done <<< "$books"
}

Technical Analysis

The first argument to recent is assigned directly to n without checking that it contains only decimal digits. It is subsequently used in Bash arithmetic contexts:

bash
[[ $count -lt $n ]]
$((n - count))

Bash arithmetic evaluation treats values as arithmetic expressions rather than inert strings. Arithmetic expressions can recursively resolve variables and array subscripts, and crafted expressions involving constructs evaluated by Bash can trigger unintended command execution. Merely quoting the original command-line argument does not make later arithmetic evaluation safe.

The argument should represent only a bounded positive integer, so accepting arbitrary arithmetic syntax exceeds the input flexibility required by the declared functionality.

Attack Path

  1. An attacker causes the wrapper to be invoked with a crafted value as the argument to recent.
  2. The value is stored unchanged in n.
  3. The loop cond ...[truncated 975 chars]
Remediation
View remediation

Remediation Suggestions

Validate and normalize the value before any arithmetic operation:

bash
cmd_recent() {
  local raw_n="${1:-10}"

  [[ "$raw_n" =~ ^[0-9]+$ ]] ||
    die "Recent count must be a positive integer"

  local n=$((10#$raw_n))
  (( n >= 1 && n <= 1000 )) ||
    die "Recent count must be between 1 and 1000"

  # Continue using only the validated numeric value.
}

Additional hardening should include:

  • Enforce a reasonable maximum to prevent excessive processing or output.
  • Use head -n "$validated_count" rather than constructing the legacy head -NUMBER form.
  • Apply explicit numeric validation to every argument later used in arithmetic expressions.
  • Add negative tests containing letters, operators, variable references, array syntax, command substitutions, whitespace, signs, and excessively large values.
  • Avoid forwarding untrusted natural-language input directly as command arguments without schema validation.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (11)

External Script Fetching

High
Category
Supply Chain
Confidence
98% confidence
Finding

curl -s https://www.getdnote.com/install | sh fetches remote content and immediately executes it without inspection or integrity verification. This creates a supply-chain and remote code execution risk if the server, connection, or install script is compromised.

Content

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

bash
# macOS/Linux auto-install
curl -s https://www.getdnote.com/install | sh

# Or Homebrew
brew install dnote

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The | sh construct is dangerous because it chains network retrieval directly into command execution, bypassing review and making compromise trivial to weaponize. In an agent-assisted environment, such patterns are especially risky because they normalize one-step execution of untrusted remote code.

Content

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

bash
# macOS/Linux auto-install
curl -s https://www.getdnote.com/install | sh

# Or Homebrew
brew install dnote

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill presents login and sync as routine operations without warning that stored notes may be transmitted to Dnote's remote service. Because notes often contain sensitive operational or personal data, users and agents may unknowingly exfiltrate information to a third party.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill documents destructive commands like note and book deletion without any warning about irreversibility or recommendation to confirm user intent first. In an agent setting, this increases the chance of accidental data loss because an automated assistant may execute management commands based on ambiguous user requests.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

Config File

Create ~/.config/dnote/dnoterc:

yaml
editor: code --wait      # or vim, nano, subl -w

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest describes saving, retrieving, searching, and organizing notes using Dnote CLI, which reads as a local personal knowledge base workflow. The script also advertises and implements sync, introducing remote server interaction that is not mentioned in the manifest and materially broadens the skill's behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Both delete operations use -y, bypassing interactive confirmation and making note or book deletion immediate. In an automated agent workflow, this materially increases the risk of accidental or prompt-induced destructive actions causing irreversible data loss.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

cmd_sync invokes dnote sync with no disclosure, guardrail, or confirmation even though syncing may upload note contents to a remote service. In an agent context, users may expect local note handling, so silent network transmission increases privacy and exfiltration risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Reading and echoing the local Dnote config file is a concrete sensitive-file exposure. In an agent setting, this can leak credentials or infrastructure details into model context, logs, or downstream tools, which is not necessary for basic note management.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/dnote.sh (reported line 302)May include surrounding context.

sh
echo "Current config:"
    cat ~/.config/dnote/dnoterc
  else
    echo "No config file found. Create one at ~/.config/dnote/dnoterc"
  fi
}

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The config command prints the user's Dnote configuration file verbatim via cat ~/.config/dnote/dnoterc. Configuration files can contain server endpoints, usernames, tokens, or other sensitive settings, so exposing them through the skill creates an unnecessary local secret disclosure path beyond normal note operations.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.