Back to skill

Security audit

BitNote

Security checks for vulnerabilities and agentic risk

Overview

BitNote is mostly coherent as an encrypted on-chain memory skill, but it handles wallet passphrases and private-key material in ways users should review carefully before installing.

Install only if you are comfortable with a skill that decrypts private-key material and can broadcast on-chain writes. Use a throwaway wallet first, keep real funds out of the account, pass secrets through a secret manager or protected environment, avoid --passphrase arguments, and do not let an agent call raw ABI admin, payout, migration, clear, or arbitrary-call functions without explicit human review.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/writeBitnoteUiCompat.mjs:47
Finding

Dry-run mode unnecessarily decrypts the wallet signing key

Content
View full analysis
extractIdHexFromBlob(b.toString()) === idHex); if (dup) { console.log('IDEMPOTENT_HIT', 'request-id already present'); console.log('ADDRESS', address); console.log('REQUEST_ID', requestId); console.log('ID_HEX', idHex); process.exit(0); } } const noteHex = await makeBitnotePayload(title, body, ecdhPub.toString(), ecdhPrivPkcs8, idHex); const noteIndex = ethers.keccak256(noteHex); if (dryRun) { console.log('DRY_RUN', 1); console.log('ADDRESS', address); console.log('REQUEST_ID', requestId); console.log('ID_HEX', idHex); console.log('NOTE_INDEX', noteIndex); process.exit(0); } ``` ### Technical Analysis The script decrypts both the ECDH private key and the secp256k1 transaction-signing private key before evaluating the `dryRun` branch. Constructing a preview note requires the ECDH key to encrypt the note payload, but it does not require the wallet’s spending key because no transaction is signed or broadcast. This violates least-privilege principles by ...[truncated 1430 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/writeBitnoteUiCompat.mjs:12
Finding

Passphrases can be supplied through exposed command-line arguments

Content
View full analysis
= 0 && process.argv[idx + 1]) return process.argv[idx + 1]; return process.env[name.toUpperCase()] ?? fallback; } const passphrase = arg('passphrase', process.env.BITNOTE_PASSPHRASE); ``` From `scripts/generateShareLink.mjs`: ```js function arg(name, fallback = null) { const idx = process.argv.indexOf(`--${name}`); if (idx >= 0 && process.argv[idx + 1]) return process.argv[idx + 1]; return process.env[name.toUpperCase()] ?? fallback; } const senderPassphrase = arg('passphrase', process.env.BITNOTE_PASSPHRASE); ``` ### Technical Analysis Both privileged scripts accept `--passphrase VALUE` through their generic command-line parser. Command-line arguments are not an appropriate secret transport mechanism because they may be exposed through: - Shell history files. - Process-listing utilities and operating-system process metadata. - Monitoring and observability agents. - Job schedulers and orchestration logs. - Diagnostic reports or command auditing systems. The documentation recommends environment variables or a secret manager, but the implementation still permits the unsafe command-line form. The passphrase protects private-key material stored in publicly retrievable blockchain records. Consequently, exposure of the passphrase may enable an attacker to obtain and decrypt the relevant wallet or ECDH private-key blobs. ### Attack Path 1. An operator invokes either privileged script using `--passphrase `. 2. The full command is recorded in shell history, process metadata, a scheduler definition, or monitoring logs. 3. A local user, sup ...[truncated 1257 chars]
Remediation
View remediation
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (22)

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/generateShareLink.mjs`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/generateShareLink.mjs`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/generateShareLink.mjs`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/generateShareLink.mjs`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/lib/bitnoteCompat.mjs`: shared compatibility helpers.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The presence of an arbitrary external call function (externalCallAuth) is a severe capability because it can enable the contract or an authorized controller to invoke other contracts with attacker-chosen calldata. In the context of a skill advertised as encrypted memory/identity storage, this is unjustified and creates a strong risk of hidden transaction execution, asset interaction, or privilege abuse beyond user expectations.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

A direct fund transfer function (sendFunds) introduces asset-movement capability unrelated to encrypted memory storage. This is dangerous because it expands the attack surface from data handling to financial custody, enabling potential draining, unauthorized payouts, or deceptive use of the skill as a wallet-like primitive without clear disclosure.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill is presented as decentralized encrypted memory, but the ABI exposes payout/withdrawal-style functions such as authPayout and authPayoutFull that enable movement of on-chain funds. In an agent-integrated context, this creates a capability mismatch that can mislead users or higher-level tooling into invoking financially sensitive operations under the guise of storage functionality.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The migrateModContract administrative function allows changing a linked contract address, which is a privileged upgrade or redirection capability not disclosed by the memory-storage description. If an agent or user trusts the skill as simple storage infrastructure, this hidden admin surface can redirect future interactions to an attacker-controlled or unsafe contract.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The ABI exposes capabilities that go beyond the declared purpose of decentralized encrypted memory, including privileged administrative and financial-style operations. This mismatch is dangerous because users or integrating agents may trust the skill as a storage/identity utility while unknowingly interacting with a broader contract surface that can change behavior, move value, or alter trust assumptions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Administrative controls for pricing, taxes, and contract verification (setBasePrice, setTaxRate, setVerifiedContractStatus) indicate mutable governance and policy mechanisms not reflected in the skill's description. This is dangerous because operators may change economic terms or trust permissions after integration, affecting downstream agents and users who believed they were using a simple encrypted-memory service.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The ABI exposes numerous state-changing and potentially destructive functions such as clearAll, clearBytesMulti, clearOwnership, authPayout, authPayoutFull, migrateModContract, and ownership transfer operations, but the manifest provides no documented trigger scope, authorization expectations, or safety constraints. In an agent-skill context, this is dangerous because an integrating agent may invoke high-impact blockchain actions without understanding who is allowed to call them, whether funds are transferred, or what irreversible state changes occur.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script reads a secret from BITNOTE_PASSPHRASE/process arguments to decrypt the sender's private key, which is a sensitive credential-handling operation. There is no confirmation prompt, user-facing warning, or explanatory comment/docstring near this behavior to disclose that the skill accesses credentials.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script performs RPC calls to a remote Avalanche endpoint and generates a share link containing sender/recipient identifiers plus encrypted content components. Although network use is inherent to the feature, the file provides no user-facing warning, logging, or documentation that usernames and related metadata are sent to or resolved via external services.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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/getAbi.mjs (reported line 10)May include surrounding context.

js
};

for (const [name, address] of Object.entries(addresses)) {
  const u = new URL("https://api.snowtrace.io/api");
  u.searchParams.set("module", "contract");
  u.searchParams.set("action", "getabi");
  u.searchParams.set("address", address);

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code file performs a safety-relevant operation by handling a user passphrase and deriving a decryption key, but there is no confirmation prompt, logging, comment, or docstring warning that sensitive credential material is being used. For code-file SQP-2, access to sensitive secrets or credentials should have some visible disclosure unless clearly documented elsewhere in the skill.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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/generateShareLink.mjs (reported line 26)May include surrounding context.

js
import modAbi from "../abi-mod.json" with { type: "json" };
import notesAbi from "../abi-notes.json" with { type: "json" };

const rpc = process.env.AVAX_RPC_URL || "https://api.avax.network/ext/bc/C/rpc";
const username = process.env.BITNOTE_USERNAME || "example_username";

const provider = new ethers.JsonRpcProvider(rpc);

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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/readBitnote.mjs (reported line 5)May include surrounding context.

js
import modAbi from "../abi-mod.json" with { type: "json" };
import notesAbi from "../abi-notes.json" with { type: "json" };

const rpc = process.env.AVAX_RPC_URL || "https://api.avax.network/ext/bc/C/rpc";
const username = process.env.BITNOTE_USERNAME || "example_username";

const provider = new ethers.JsonRpcProvider(rpc);

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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/writeBitnoteUiCompat.mjs (reported line 31)May include surrounding context.

js
import modAbi from "../abi-mod.json" with { type: "json" };
import notesAbi from "../abi-notes.json" with { type: "json" };

const rpc = process.env.AVAX_RPC_URL || "https://api.avax.network/ext/bc/C/rpc";
const username = process.env.BITNOTE_USERNAME || "example_username";

const provider = new ethers.JsonRpcProvider(rpc);

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script accepts a sensitive passphrase from CLI arguments or environment variables, decrypts private key material, and can immediately submit an on-chain transaction without any interactive confirmation step. In an agent or automation context, this raises the risk of unintended secret use and irreversible blockchain writes from misconfiguration, prompt injection into higher-level tooling, shell history exposure, or accidental invocation.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This file is a JSON manifest-type artifact, so vague-trigger checks apply. It lists callable operations such as "authPayoutFull", "migrateModContract", and "setDataAtIndex" but provides no natural-language description of when these operations should be invoked, any limiting context, or exclusion conditions, which can make activation scope ambiguous if this artifact is used to drive tool/skill selection.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency version for ethers is specified with a caret range (^6.16.0), which allows future compatible releases to be installed automatically. This can introduce supply-chain risk if a newly published version contains a vulnerability or malicious code, and the risk is somewhat more relevant here because the skill handles secrets, identity, and memory where dependency trust is especially important.

Content

Scanner excerpt · package.json (reported line 13)May include surrounding context.

json
"author": "",
  "license": "ISC",
  "dependencies": {
    "ethers": "^6.16.0"
  }
}

Static analysis

No suspicious patterns detected.