Back to skill

Security audit

HackMD

Security checks for vulnerabilities and agentic risk

Overview

This HackMD skill is mostly coherent, but it deserves review because it can guide note deletion and its tracking script can send the HackMD API token to any endpoint set in the environment.

Review this skill before installing. Use a least-privileged HackMD token, keep HMD_API_ENDPOINT_URL unset unless you intentionally use a trusted HackMD-compatible deployment, and require explicit confirmation before any create, update, or delete operation on personal or team notes.

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/hackmd-track.js:15
Finding

HackMD bearer token can be transmitted to an arbitrary API host

Content
View full analysis
{ if (!API_TOKEN) { reject(new Error("HMD_API_ACCESS_TOKEN not set")); return; } // Ensure endpoint starts with / const fullPath = endpoint.startsWith("/") ? endpoint : `/${endpoint}`; const baseUrl = API_BASE.endsWith("/v1") ? API_BASE : `${API_BASE}/v1`; const url = new URL(baseUrl); const options = { hostname: url.hostname, port: 443, path: `/v1${fullPath}`, method: "GET", headers: { Authorization: `Bearer ${API_TOKEN}`, "Content-Type": "application/json", }, }; const req = https.request(options, (res) => { let data = ""; res.on("data", (chunk) => (data += chunk)); res.on("end", () => { i ...[truncated 3138 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The description claims a general-purpose HackMD skill for reading, creating, updating, or deleting notes, with change tracking. The supplied code only performs read-only API access to note metadata/content and maintains a local state file for change detection. It supports adding/removing notes from local tracking, listing tracked notes, resetting tracking state, and checking for changes, but it never issues POST, PATCH, PUT, or DELETE requests to create, modify, or delete HackMD documents. Thus the declared description materially overstates the implemented capabilities. The change-tracking portion is accurately represented, but the broader CRUD description is not.

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

md
Use `hackmd-track.js` (in `scripts/`) to detect document changes efficiently.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Use `hackmd-track.js` (in `scripts/`) to detect document changes efficiently.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Use `hackmd-track.js` (in `scripts/`) to detect document changes efficiently.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Use `hackmd-track.js` (in `scripts/`) to detect document changes efficiently.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Use `hackmd-track.js` (in `scripts/`) to detect document changes efficiently.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Use `hackmd-track.js` (in `scripts/`) to detect document changes efficiently.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Use `hackmd-track.js` (in `scripts/`) to detect document changes efficiently.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
Use `hackmd-track.js` (in `scripts/`) to detect document changes efficiently.

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · scripts/hackmd-track.js (reported line 145)May include surrounding context.

js
}

    const title = state.notes[noteId].title;
    delete state.notes[noteId];
    saveState(state);

    console.log(`Stopped tracking: ${title || noteId}`);

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill documents destructive deletion commands without any warning, confirmation guidance, or safer alternatives. In an agent context, this increases the chance of accidental or over-broad note deletion, especially because the same API token may have access to personal and team workspaces where mistakes can affect shared data.

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 · scripts/hackmd-track.js (reported line 14)May include surrounding context.

js
const STATE_FILE = path.join(STATE_DIR, "tracked-notes.json");

// API config
const API_BASE = process.env.HMD_API_ENDPOINT_URL || "https://api.hackmd.io/v1";
const API_TOKEN = process.env.HMD_API_ACCESS_TOKEN;

// Ensure state directory exists

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/hackmd-track.js (reported line 380)May include surrounding context.

js
const STATE_FILE = path.join(STATE_DIR, "tracked-notes.json");

// API config
const API_BASE = process.env.HMD_API_ENDPOINT_URL || "https://api.hackmd.io/v1";
const API_TOKEN = process.env.HMD_API_ACCESS_TOKEN;

// Ensure state directory exists

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/hackmd-track.js (reported line 38)May include surrounding context.

js
}
}

// Save state to file
function saveState(state) {
    ensureStateDir();
    fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));

Static analysis

No suspicious patterns detected.