Back to skill

Security audit

Caring CourseForge

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real CourseForge integration, but it gives an agent broad credentialed authority over course content, storage, and API keys without enough built-in scoping or safety controls.

Install only if you trust the CourseForge npm client and publisher, use a narrowly scoped CourseForge API key where possible, avoid setting COURSEFORGE_API_URL unless you control the endpoint, and require explicit human confirmation before deletes, rollbacks, exports, API-key changes, or bulk content changes.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
Findings (3)

T08 · Insecure Dependencies

Error
Location
scripts/courseforge.mjs:32
Finding
Third-Party npm Package Is Automatically Downloaded and Executed with API Credentials## Vulnerability Details **File Location**: `SKILL.md:9-16, 27`; `scripts/courseforge.mjs:32-56` **Vulnerability Type**: Supply-chain exposure through automatic dependency retrieval and execution **Risk Level**: High ### Vulnerable Code `SKILL.md:9-16`: ```yaml requires: bins: ["node"] env: ["COURSEFORGE_API_KEY"] install: - id: npm kind: npm package: courseforge-mcp-client global: true bins: ["courseforge-mcp"] label: "Install CourseForge MCP client (npm)" ``` `SKILL.md:27`: ```bash npm install -g courseforge-mcp-client ``` `scripts/courseforge.mjs:32-56`: ```js // Find the courseforge-mcp binary, fall back to npx const home = process.env.HOME || ''; const candidates = [ resolve(home, '.npm-global/bin/courseforge-mcp'), resolve(home, '.local/bin/courseforge-mcp'), '/usr/local/bin/courseforge-mcp', ]; let mcpBin = null; let mcpArgs = []; for (const c of candidates) { if (existsSync(c)) { mcpBin = c; break; } } if (!mcpBin) { // Fall back to npx with pinned version mcpBin = 'npx'; mcpArgs = ['-y', 'courseforge-mcp-client@1.3.0']; } // Only pass required env vars to the child process — avoid leaking unrelated secrets const child = spawn(mcpBin, mcpArgs, { env: { COURSEFORGE_API_KEY: process.env.COURSEFORGE_API_KEY, COURSEFORGE_API_URL: process.env.COURSEFORGE_API_URL || '', HOME: process.env.HOME || '', PATH: process.env.PATH || '', NODE_PATH: process.env.NODE_PATH || '', npm_config_prefix: process.env.npm_config_prefix || '', }, ``` ### Technical Analysis The documented installation command installs the latest published version of `courseforge-mcp-client` globally without an exact version or integrity constraint. If no existing binary is found, the wrapper automatically invokes `npx -y` to download and execute version `1.3.0`. Although the fallback uses an exact version number, ...[truncated 1954 chars]
Remediation
## Remediation Suggestions - Pin the documented global installation to an exact, reviewed version rather than installing the latest release. - Commit a lockfile with npm integrity metadata or vendor the reviewed MCP client. - Remove the automatic `npx -y` fallback. Fail closed and require an administrator to install and verify the client explicitly. - Verify the selected executable and package against an approved checksum or signature before execution. - Run the client in a sandbox with restricted filesystem access and outbound network access limited to approved CourseForge endpoints. - Use a narrowly scoped and short-lived token rather than an account-wide API key. - Separate read, write, destructive, and API-key-management privileges where the service supports scoped credentials. - Require explicit confirmation before destructive operations or API-key creation and revocation.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/courseforge.mjs:51
Finding
Unrestricted API Endpoint Override Can Redirect the CourseForge Credential## Vulnerability Details **File Location**: `scripts/courseforge.mjs:51-56` **Vulnerability Type**: Unsafe credential destination configuration **Risk Level**: High ### Vulnerable Code ```js const child = spawn(mcpBin, mcpArgs, { env: { COURSEFORGE_API_KEY: process.env.COURSEFORGE_API_KEY, COURSEFORGE_API_URL: process.env.COURSEFORGE_API_URL || '', HOME: process.env.HOME || '', PATH: process.env.PATH || '', NODE_PATH: process.env.NODE_PATH || '', npm_config_prefix: process.env.npm_config_prefix || '', }, ``` ### Technical Analysis The wrapper forwards both the secret API key and a user-controlled `COURSEFORGE_API_URL` value to the external MCP client. It does not validate the URL scheme, hostname, port, or destination against an allowlist. The Skill documentation describes communication with `caringcourseforge.com`, so unrestricted endpoint substitution is broader than the minimum privilege necessary for normal production operation. If the external client uses `COURSEFORGE_API_URL` as its authentication destination, a poisoned environment can redirect the credential to an attacker-controlled service. The actual request construction occurs inside the external npm package and is not available in this repository. Consequently, the audit cannot prove that every client version transmits the key to the override URL. Nevertheless, the wrapper creates the complete prerequisite for credential redirection by passing an unvalidated destination and the credential to the same process. ### Attack Path 1. An attacker, malicious launcher, compromised shell configuration, or CI configuration sets `COURSEFORGE_API_URL` to an attacker-controlled endpoint. 2. The user invokes `scripts/courseforge.mjs` with a valid production API key. 3. The wrapper performs no endpoint validation and supplies both values to `courseforge-mcp`. 4. The external client connects to the substituted endpoint and includes t ...[truncated 797 chars]
Remediation
## Remediation Suggestions - Remove `COURSEFORGE_API_URL` override support from production builds if it is not required. - If endpoint overrides are necessary for testing, require an explicit development mode and reject production credentials in that mode. - Parse the URL and require HTTPS. - Allowlist the exact official CourseForge hostname and expected port. - Reject URLs containing embedded credentials, unexpected ports, IP literals, redirects to unapproved origins, or non-HTTPS schemes. - Bind credentials to the expected audience or service origin when supported by the API. - Use separate, low-privilege credentials for development and staging endpoints. - Log the selected destination without logging the API key, so endpoint changes are visible during security review.

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:101
Finding
Remote Skill Definitions Are Reused as Agent Context Without an Explicit Trust Boundary## Vulnerability Details **File Location**: `SKILL.md:101-106`; `references/tools.md:678-694` **Vulnerability Type**: Indirect prompt injection through remotely retrieved Skill content **Risk Level**: Medium ### Vulnerable Code `SKILL.md:101-106`: ```markdown ### Use domain skills for specialized content 1. `list_skills` — see all 17 available specialist skills 2. `get_skill` — load a skill (e.g., "Instructional Designer", "HR Specialist") 3. Use the skill context when generating content with `ai_chat_assistant` ``` `references/tools.md:678-694`: ```markdown ## Skills ### `list_skills` List all available CourseForge skills. Skills are domain-specific expertise modules that provide guidance for creating training content in specific fields. | Param | Type | Req | Description | |-------|------|-----|-------------| | `category` | string | | Filter skills by category (default: all) | ### `get_skill` Get the full content of a specific CourseForge skill. Returns the complete skill definition including role, capabilities, module structures, best practices, and recommended tools. | Param | Type | Req | Description | |-------|------|-----|-------------| | `skillId` | string | ✅ | Skill ID (e.g., "course-builder", "salesforce-specialist", "ocm-specialist") | ``` ### Technical Analysis The recommended workflow retrieves mutable content from a remote service, including a role definition, capabilities, best practices, and recommended tools, and then directs the agent to use that content as context for subsequent AI calls. No instruction establishes that the retrieved definition is untrusted data. There is also no documented field allowlist, sanitization step, instruction-precedence rule, or prohibition against treating remote recommendations as authorization for additional tool calls. This creates an indirect prompt-injection boundary. A compromised CourseForge service, compromised Skill authoring acco ...[truncated 1858 chars]
Remediation
## Remediation Suggestions - Explicitly label all `get_skill` responses as untrusted reference material rather than executable instructions. - State that remote Skill content cannot override system instructions, user intent, safety constraints, or authorization requirements. - Parse and allowlist expected informational fields instead of injecting the complete returned definition into agent context. - Strip or quarantine text that attempts to direct tool use, request secrets, change instruction priority, or expand task scope. - Do not include API keys, private documents, unrelated conversation history, or other sensitive context in AI calls merely because remote content requests it. - Require explicit user confirmation before deletion, publication, export, upload, API-key management, rollback, or other consequential operations. - Display the source and relevant retrieved content to the user before applying remote recommendations. - Use signed, versioned, and administrator-approved remote Skill definitions where supported.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (14)

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill requests access to a sensitive environment variable (`COURSEFORGE_API_KEY`) and instructs the agent to invoke a Node-based wrapper, but it does not declare any explicit tool scope or allowed-tools boundary. Without a permission model in the skill, an agent or downstream wrapper could use the available environment-backed credentials for broader actions than the user expected, increasing the risk of unauthorized API operations.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documented toolset includes destructive and account-affecting operations such as `delete_course`, `delete_module`, `delete_lesson`, `delete_document`, `delete_storage_file`, `revoke_api_key`, and rollback/checkpoint actions, but the skill provides no cautionary guidance or confirmation requirement. In an agent setting, this makes accidental or prompt-induced destructive changes more likely, especially because the same skill also exposes credentialed API access and broad management capabilities.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
`delete_course` is a destructive operation, but the reference provides no guidance that agents should obtain explicit user confirmation or warn about irreversible data loss. In an LLM-driven environment, omission of safety expectations makes accidental or prompt-induced deletion materially more likely.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
`delete_module` and `delete_lesson` remove core course structure, yet the tool reference lacks warnings or required confirmation steps. Because these operations are easy for an agent to invoke during editing workflows, missing safety guidance increases the risk of unintended content loss.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The reference states that content block deletion permanently removes the block and its content, but it still does not prescribe a user confirmation or safer workflow. Permanent fine-grained deletion is especially risky in agentic editing because a mistaken block ID or prompt injection can silently erase instructional content.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
Document and file deletion operations in the knowledge library can destroy user data, but the reference omits warnings about irreversibility and confirmation expectations. Since these assets may feed AI course generation, accidental deletion can also indirectly degrade future outputs and knowledge integrity.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
`delete_storage_file` can remove generated images, exports, and uploaded files from Firebase Storage, but no safety or confirmation guidance is included. Because the parameter may be either a direct path or download URL, misuse could lead to broad or mistaken file deletion with limited visibility to the user.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The web fetch/scrape capabilities allow the agent to retrieve external content, but the reference does not warn about privacy, copyright, or data-handling implications of sending user-supplied URLs to external sites and ingesting their contents. In agent workflows, this can enable exfiltration of sensitive URLs, retrieval of untrusted content, or inadvertent processing of regulated data.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The documented toolset includes API key lifecycle operations (`list_api_keys`, `create_api_key`, `revoke_api_key`), which expand the skill from course authoring into credential management. In an agent context, unrelated secret-management capabilities increase blast radius: a prompt-injected or over-permissive workflow could mint or revoke credentials and enable persistence or denial of service beyond the user’s immediate course task.

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.

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.

Missing User Warnings

Low
Confidence
79% confidence
Finding
`ai_chat_with_research` includes optional web research, but the reference does not clearly warn that enabling research may trigger external web access and data disclosure beyond the platform. This is lower severity than deletion issues, yet it still matters because users may assume the interaction stays local to CourseForge.

Context-Inappropriate Capability

Low
Confidence
88% confidence
Finding
The manifest describes a skill for course creation, content generation, export, knowledge libraries, and CourseForge platform interaction in the context of course building. A `marketing_support_chat` tool for pricing, features, documentation, and support requests is a customer-support/marketing function rather than a course-authoring capability.

Missing User Warnings

Low
Confidence
82% confidence
Finding
This code spawns an external MCP client process, and while comments describe usage, there is no runtime user-facing notice, confirmation, or explicit warning that the wrapper will execute a child process. For a code file, subprocess execution is in scope for missing-warning review unless the disclosure is clearly visible to the user or explicitly documented as part of the skill behavior.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/courseforge.mjs:51