Back to skill

Security audit

Ghost CMS

Security checks for vulnerabilities and agentic risk

Overview

Review before installing: the Ghost CMS access is mostly disclosed and purpose-related, but the package includes a script that can overwrite a hard-coded Ghost post and a theme download path bug that can write outside the intended directory.

Install only if you are comfortable granting full Ghost Admin access. Use a staging site or a dedicated integration key, avoid running scripts/update-teapot.js, review all publish/delete/theme commands before execution, and be cautious with theme downloads until the output-path validation is fixed.

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/theme-manager.js:143
Finding

Output Directory Containment Check Can Be Bypassed Using Sibling Paths

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/update-teapot.js:465
Finding

Bundled Script Unconditionally Overwrites a Hard-Coded Ghost Post

Content
View full analysis
{ console.log('Success! Updated post:'); console.log(JSON.stringify(result, null, 2)); }) .catch(err => { console.error('Error:', err.message); process.exit(1); }); ``` The script obtains full-access credentials earlier in the file: ```js const configDir = path.join(process.env.HOME, '.config', 'ghost'); const apiKey = fs.readFileSync(path.join(configDir, 'api_key'), 'utf8').trim(); const apiUrl = fs.readFileSync(path.join(configDir, 'api_url'), 'utf8').trim(); ``` ### Technical Analysis Executing `scripts/update-teapot.js` immediately reads the user's Ghost Admin API credentials, generates an authenticated JWT, and sends an HTTP `PUT` request to a fixed post identifier. The request replaces the post's Lexical content with the large article embedded in the script. The script does not require a user-supplied post ID, display the existing post before modification, support a dry-run mode, request confirmation, or create a backup. It is also not presented as one of the primary tools in the Skill documentation. Consequently, invocation of what appears to be a development or example utility can modify real Ghost data without an explicit target-selection step. Ghost Admin API integration keys are documented as unscoped and full-access. The request is therefore authorized to alter the target post whenever that identifier exists on the configured Ghost instance. ### Attack Path 1. A user, automation process, or Agent in ...[truncated 1459 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (96)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description promises a comprehensive Ghost CMS integration with broad operational coverage across content management, members, newsletters, moderation, analytics, and all Ghost Admin API operations. The supplied code does something much narrower: it authenticates to Ghost Admin API using a locally stored key and URL, validates an endpoint string, and issues a single API request from the command line. Although the helper function technically accepts method and data parameters, the exposed CLI path only uses the endpoint argument and performs a GET request. There is no implemented logic for creating or publishing posts, scheduling content, managing members or newsletters, moderating comments, or retrieving analytics-specific summaries. Therefore the description materially overstates the actual behavior and capabilities of this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The code accurately supports part of the description related to blog content creation, publishing, scheduling, and post management. However, the declared description significantly overstates scope: this script only interacts with Ghost post endpoints and provides CRUD plus publish/schedule actions for posts. There is no implementation for newsletters, members, subscription tiers, comments, analytics, or the full range of Ghost Admin API operations. Reading local API credentials and generating JWTs are supporting details, not mismatches. The material mismatch is that the declared purpose describes a comprehensive Ghost integration, while the actual behavior is a narrow post-management utility.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The description presents this skill as a full-featured Ghost CMS integration supporting essentially all admin workflows. The supplied code chunk is much narrower: it is a content-formatting helper that builds Ghost Lexical documents and card payloads, plus a small CLI for converting text/JSON into Lexical JSON. While this supports Ghost content creation indirectly, it does not interact with Ghost APIs, authenticate, manage posts remotely, handle members, moderate comments, or retrieve analytics. Therefore the declared description materially overstates the implemented behavior and primary purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The description substantially overstates the skill's scope. The code is not a comprehensive Ghost CMS integration; it is a specialized snippet-extraction script. Its only Ghost interaction is reading a specific post via the Admin API. It does not create or manage posts, newsletters, members, comments, or analytics. Additionally, it writes extracted snippets to local JSON files, which is a concrete behavior absent from the declared purpose. This is a clear description-behavior mismatch in primary purpose and supported capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The description presents a broad, comprehensive Ghost CMS skill for managing content, newsletters, members, comments, and analytics across the Ghost Admin API. The supplied code does something much narrower: it is a standalone CLI script dedicated to theme management. Its actual API usage is limited to /themes endpoints for listing, uploading, activating, deleting, and downloading themes, plus writing downloaded ZIP files locally. This is a materially different primary purpose from the declared description, and most advertised capabilities are absent. Therefore the description does not accurately represent the code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This is a clear description-behavior mismatch. The declared purpose describes a broad Ghost CMS integration focused on Admin API functionality for managing content, members, comments, newsletters, and analytics. The supplied code instead implements a command-line theme validator for local theme directories/ZIPs using gscan. Its inputs are filesystem paths and CLI flags; its outputs are console messages/JSON and process exit codes. There is no network communication, no authentication, no Ghost Admin API usage, and no CMS management capabilities. Theme validation is Ghost-related, but it is materially different from the declared primary purpose and omitted from the description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description describes a broad, general-purpose Ghost CMS skill with support for many Admin API domains. The supplied code is much narrower: it is a one-off script that authenticates to Ghost and updates a single hardcoded post using a PUT request. While it does interact with the Ghost Admin API, it does not expose or implement the wide range of capabilities claimed in the description. This is a material description-to-behavior mismatch due to overstating scope and functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description says this skill is a broad Ghost CMS integration supporting creation, publishing, scheduling, management of content, newsletters, members, comments, analytics, and all Ghost Admin API operations. The supplied code does something much narrower and materially different: it manages local JSON snippet files on disk and can inject snippet cards into a Lexical document structure. Its operations are local file I/O (load/save/list/delete/copy snippets) plus content array insertion. There are no network calls, no Ghost API usage, no authentication, and no logic for posts, newsletters, members, comments, or analytics. This is a clear description-behavior mismatch because the primary purpose and capabilities are substantially different from what is declared.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The code chunk does not interact with Ghost CMS, network APIs, blog content, members, comments, or analytics at all. Its actual purpose is managing local snippet-library storage and configuration on disk, including reading environment variables, creating directories, saving a config JSON file, and migrating local snippet files. This is a materially different primary purpose from the declared comprehensive Ghost CMS integration, so the description does not accurately represent the code.

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

md
node scripts/snippet-extractor.js my-snippets-post

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/snippet-extractor.js my-snippets-post

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/snippet-extractor.js my-snippets-post

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/snippet-extractor.js my-snippets-post

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/snippet-extractor.js my-snippets-post

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/snippet-extractor.js my-snippets-post

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/snippet-extractor.js my-snippets-post

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/snippet-extractor.js my-snippets-post

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/snippet-extractor.js my-snippets-post

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/snippet-extractor.js my-snippets-post

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/snippet-extractor.js my-snippets-post

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/snippet-extractor.js my-snippets-post

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/api-reference.md (reported line 42)May include surrounding context.

md
**Content Management:**
- **POST /posts/** - Create draft post
- **PUT /posts/:id/** - Update post (can publish if status changed!)
- **DELETE /posts/:id/** - Delete post permanently
- **POST /pages/** - Create page
- **PUT /pages/:id/** - Update page (can publish!)
- **DELETE /pages/:id/** - Delete page permanently

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/api-reference.md (reported line 45)May include surrounding context.

md
- **DELETE /posts/:id/** - Delete post permanently
- **POST /pages/** - Create page
- **PUT /pages/:id/** - Update page (can publish!)
- **DELETE /pages/:id/** - Delete page permanently

**🚨 CRITICAL:** Setting `status: "published"` makes content **immediately public**

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/api-reference.md (reported line 52)May include surrounding context.

md
**Organization:**
- **POST /tags/** - Create tag
- **PUT /tags/:id/** - Update tag
- **DELETE /tags/:id/** - Delete tag (affects all tagged posts)

**Members & Subscriptions:**
- **POST /members/** - Add member

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/api-reference.md (reported line 57)May include surrounding context.

md
**Members & Subscriptions:**
- **POST /members/** - Add member
- **PUT /members/:id/** - Update member (can change subscription status)
- **DELETE /members/:id/** - Delete member permanently
- **POST /tiers/** - Create pricing tier
- **PUT /tiers/:id/** - Update tier pricing/benefits
- **DELETE /tiers/:id/** - Archive tier

Static analysis

Detected: suspicious.generated_source_template_injection

User-controlled placeholder is embedded directly into generated source code.

Critical
Code
suspicious.generated_source_template_injection
Location
references/analytics.md:240