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## 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
## 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## 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
## 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
Content
```bash
# macOS/Linux auto-install
curl -s https://www.getdnote.com/install | sh

# Or Homebrew
brew install dnote
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.

Chaining Abuse

High
Category
Tool Misuse
Content
```bash
# macOS/Linux auto-install
curl -s https://www.getdnote.com/install | sh

# Or Homebrew
brew install dnote
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.

Missing User Warnings

Medium
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.

Missing User Warnings

Medium
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.

Session Persistence

Medium
Category
Rogue Agent
Content
## Config File

Create `~/.config/dnote/dnoterc`:

```yaml
editor: code --wait      # or vim, nano, subl -w
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.

Description-Behavior Mismatch

Medium
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.

Missing User Warnings

Medium
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.

Missing User Warnings

Medium
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.

Context-Inappropriate Capability

Medium
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.

Session Persistence

Medium
Category
Rogue Agent
Content
echo "Current config:"
    cat ~/.config/dnote/dnoterc
  else
    echo "No config file found. Create one at ~/.config/dnote/dnoterc"
  fi
}
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.

Description-Behavior Mismatch

Low
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.

Static analysis

No suspicious patterns detected.