Back to skill

Security audit

Hardcover Bookshelf Skill

Security checks for vulnerabilities and agentic risk

Overview

This skill appears intended to manage a Hardcover reading account, but it combines account-changing commands and token access with under-scoped execution and unpinned npx-based runtime dependencies.

Review before installing. Use this only if you are comfortable giving the skill a Hardcover API token and allowing it to change your reading status. Prefer running it from a lockfile-pinned install, avoid npx downloading packages at runtime, and confirm start/finish actions before letting an agent execute them.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Warning
Location
package.json:6
Finding

Unpinned Dependencies Executed Through npx

Content
View full analysis

Vulnerability Details

File Location: package.json:6-12; related instructions in SKILL.md:55-58 and README.md:90-93
Vulnerability Type: Supply-chain exposure through mutable dependency resolution and npx execution
Risk Level: Medium

Vulnerable Code

json
"scripts": {
  "list": "npx tsx src/cli.ts list",
  "start": "npx tsx src/cli.ts start",
  "finish": "npx tsx src/cli.ts finish",
  "count-last-year": "npx tsx src/cli.ts count-last-year",
  "test": "vitest run --exclude 'src/**/*.integration.test.ts'",
  "test:integration": "vitest run src/client.integration.test.ts"
},
"devDependencies": {
  "tsx": "^4",
  "vitest": "^3"
}

The documented commands also directly use npx:

bash
npx tsx src/cli.ts list [--limit 20] [--json]
npx tsx src/cli.ts start --title "The Complete Maus" [--json]
npx tsx src/cli.ts finish --title "The Complete Maus" [--json]
npx tsx src/cli.ts count-last-year [--json]

Technical Analysis

The Skill executes the third-party tsx package through npx, while its dependencies use non-exact version ranges and the project contains no reviewed lockfile. Consequently, installation is not reproducible: npm install may resolve a newer package version than the version reviewed during this audit.

If the local tsx executable is unavailable, npx may retrieve and execute a package from the configured npm registry. The effective executable can therefore depend on registry state, package publication changes, local npm configuration, or a compromised package release.

This is particularly sensitive because the commands run in a process that can access HARDCOVER_TOKEN. Although the audited source sends that credential only to the fixed Hardcover HTTPS endpoint, third-party code executed before or alongside the client has the same process-level ability to read environment variables.

No evidence was found that the current declared dependencies are malicious. The vulnerability is the absence of reproduci ...[truncated 1408 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin all dependencies to reviewed exact versions rather than permissive ranges:
json
"devDependencies": {
  "tsx": "4.x.y",
  "vitest": "3.x.y"
}
  1. Generate and commit package-lock.json, and require deterministic installation with:
bash
npm ci
  1. Avoid allowing npx to download packages during normal Skill execution. Invoke the verified local binary through an offline-enforced command, for example:
bash
npm exec --offline -- tsx src/cli.ts list

Alternatively, expose fixed npm scripts that invoke the locally installed binary and ensure installation is completed before credentials are supplied.

  1. Configure CI to reject dependency or lockfile drift and review dependency updates before release.

  2. Run dependency integrity and vulnerability checks during release preparation, including:

bash
npm audit
npm ci
  1. Where practical, run the Skill with a minimal environment containing only HARDCOVER_TOKEN and restrict filesystem and network access to reduce the impact of a compromised dependency.

  2. Document that commands must not fall back to runtime registry retrieval and that only lockfile-verified installations are supported.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (49)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose describes a production skill for managing Hardcover bookshelf activity via the Hardcover GraphQL API. The actual code only implements a helper to load environment variables from a local .env file and pass them into Vitest test configuration. This is materially different in primary purpose and behavior. While loading environment variables could be a supporting detail in a larger Hardcover integration, this code chunk itself contains none of the claimed API access or bookshelf-management behavior, and instead performs unrelated test configuration and filesystem access.

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

md
npx tsx src/cli.ts list [--limit 20] [--json]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
npx tsx src/cli.ts list [--limit 20] [--json]

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
npx tsx src/cli.ts list [--limit 20] [--json]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
npx tsx src/cli.ts list [--limit 20] [--json]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
npx tsx src/cli.ts list [--limit 20] [--json]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
npx tsx src/cli.ts list [--limit 20] [--json]

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
npx tsx src/cli.ts list [--limit 20] [--json]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
npx tsx src/cli.ts list [--limit 20] [--json]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
npx tsx src/cli.ts list [--limit 20] [--json]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `src/client.ts` — Hardcover API client and common operations

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 · vitest.config.ts (reported line 7)May include surrounding context.

ts
function loadDotenv(): Record<string, string> {
  try {
    const content = readFileSync(resolve(process.cwd(), '.env'), 'utf-8');
    const env: Record<string, string> = {};
    for (const line of content.split('\n')) {
      const trimmed = line.trim();

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README describes commands that change a user's remote Hardcover account state, such as marking books started or finished, without clearly warning that these actions modify live account data. In an agent skill context, that omission is more dangerous because users may treat natural-language prompts as informational and not realize the skill will perform persistent remote updates.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares access to environment variables and networked API behavior, but does not constrain tool scope with explicit permissions or allowed-tools. In practice this can let an agent invoke broader capabilities than necessary when handling a user request, increasing the blast radius if the skill is misrouted or later modified.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The invocation guidance says to use the skill whenever the user mentions Hardcover, reading lists, bookshelves, tracking books, or anything related to managing what they're reading. That broad phrasing can cause the agent to route general book conversations into a credentialed skill with network and mutation capability, raising the chance of unnecessary token prompts or unintended actions.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The install metadata indicates Node-based installation with npx-driven execution, but no version pinning is specified. Unpinned package resolution can fetch different code over time or pull a compromised upstream dependency, creating a supply-chain execution risk at install or runtime.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding

The documented command uses npx tsx src/cli.ts, which relies on package resolution that may execute an unexpected or newly changed tsx package if the environment is not fully pinned. Because this command is intended to run code with access to HARDCOVER_TOKEN and network access, a supply-chain compromise could expose credentials or alter API actions.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding

This command invocation depends on unpinned npx tsx execution for a state-changing action (start). If an attacker influences package resolution or upstream dependencies, arbitrary code could run before or during a write operation using the user's token.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding

The finish command is another write path run via unpinned npx tsx. This creates a supply-chain risk in a context where the process has both credential access and permission to mutate a user's reading history.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

Even for a read-oriented command like count-last-year, unpinned npx tsx can execute unexpected code from the package ecosystem. The presence of HARDCOVER_TOKEN in the environment means a compromise could still leak secrets or perform unauthorized network actions.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding

This repeated npx tsx usage for listing bookshelf contents carries the same dependency-execution risk. Because the process can read HARDCOVER_TOKEN, a malicious or substituted package could exfiltrate the token even during a nominally read-only operation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding

The start-reading flow is documented with unpinned npx tsx, combining supply-chain exposure with a mutating API call. This is especially sensitive because the command may be run automatically by an agent after natural-language interpretation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding

The finish-reading flow has the same unpinned package execution issue in a credentialed, mutating context. An attacker controlling dependency resolution could alter records or steal the bearer token.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The stats command still uses unpinned npx tsx, exposing the environment to registry-sourced code execution. Although the intended action is read-only, the token and network capability make compromise consequential.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.