Back to skill

Security audit

Felo Slides

Security checks for vulnerabilities and agentic risk

Overview

The skill is broadly aligned with generating slides through Felo, but it has review-worthy risks around redirectable API traffic and an unpinned installer command.

Before installing, prefer a pinned or manually reviewed source instead of the unpinned `npx` command. Use a dedicated, revocable Felo API key, do not set `FELO_API_BASE` unless you fully trust the destination, and assume any prompt used to generate slides will be sent to Felo's API.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run_ppt_task.mjs:179
Finding
Unrestricted API Base Override Can Expose API Credentials and User Prompts<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run_ppt_task.mjs:139-173, 179-185` **Vulnerability Type**: Unvalidated network destination for sensitive data **Risk Level**: High ### Vulnerable Code ```js async function createTask(apiKey, apiBase, query, timeoutMs, theme) { const reqBody = { query }; if (theme) { reqBody.ppt_config = { ai_theme_id: theme }; } const payload = await fetchJson( `${apiBase}/v2/ppts`, { method: 'POST', headers: { Accept: 'application/json', Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json', }, body: JSON.stringify(reqBody), }, timeoutMs ); const data = payload?.data ?? {}; if (!data.task_id) { throw new Error('Unexpected response: missing task_id'); } return data; } async function queryHistorical(apiKey, apiBase, taskId, timeoutMs) { const payload = await fetchJson( `${apiBase}/v2/tasks/${encodeURIComponent(taskId)}/historical`, { method: 'GET', headers: { Accept: 'application/json', Authorization: `Bearer ${apiKey}`, }, }, timeoutMs ); return payload?.data ?? {}; } ``` ```js const apiKey = process.env.FELO_API_KEY?.trim(); if (!apiKey) { console.error('ERROR: FELO_API_KEY not set'); process.exit(1); } const apiBase = (process.env.FELO_API_BASE?.trim() || DEFAULT_API_BASE).replace(/\/$/, ''); ``` ### Technical Analysis The script obtains the sensitive `FELO_API_KEY` environment variable and sends it in the `Authorization` header to the URL selected through `FELO_API_BASE`. The same destination receives the complete presentation prompt through the task-creation request. The value of `FELO_API_BASE` is not validated. In particular, the implementation does not: - Require HTTPS. - Restrict the hostname to an approved Felo API domain. - Reject URLs containing embedded credentials or unexpected components. - Prevent requests to attacker-controlled, ...[truncated 1847 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove support for `FELO_API_BASE` if a custom API endpoint is not an explicit functional requirement. 2. If endpoint customization is required, parse it with the `URL` class and enforce: - `https:` as the only permitted protocol. - An explicit allowlist of trusted hostnames, preferably only `openapi.felo.ai`. - No username or password URL components. - No unexpected path, query, or fragment components in the configured base URL. 3. Disable automatic redirects or validate every redirect target before forwarding the `Authorization` header. 4. Never forward bearer credentials across origins. 5. Fail closed with a clear error when endpoint validation fails. 6. Document that prompts are transmitted to Felo and advise users not to include unnecessary secrets or regulated data. 7. Consider separating development endpoint support into an explicit command-line option that requires affirmative user consent rather than implicitly trusting an environment variable. Example validation: ```js function validateApiBase(value) { const url = new URL(value || DEFAULT_API_BASE); if ( url.protocol !== 'https:' || url.hostname !== 'openapi.felo.ai' || url.username || url.password || url.search || url.hash ) { throw new Error('FELO_API_BASE must use the approved HTTPS Felo API endpoint'); } return url.origin; } ``` ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:18
Finding
Unpinned npm Package Is Downloaded and Executed During Installation<![CDATA[ ## Vulnerability Details **File Location**: `README.md:18-20` **Vulnerability Type**: Unpinned executable supply-chain dependency **Risk Level**: Medium ### Vulnerable Code ```bash npx skills add Felo-Inc/felo-skills --skill felo-slides ``` ### Technical Analysis The recommended installation command invokes the unversioned `skills` npm package through `npx`. Depending on the local npm configuration and cache state, `npx` can download the current package release from the configured registry and execute it immediately. The package version, integrity digest, and audited source are not fixed by the command. Consequently, the code executed during installation can change after this Skill has been reviewed. This creates a supply-chain trust dependency outside the audited project contents. No evidence in the reviewed files establishes that the current `skills` package is malicious. The risk arises from executing mutable third-party installer code without version or integrity controls. ### Attack Path 1. The npm package, its publisher account, or the package registry is compromised, or a future package release introduces malicious behavior. 2. A user follows the README and runs the documented `npx skills add ...` command. 3. `npx` resolves and downloads the mutable package version available through the configured registry. 4. The downloaded package executes with the privileges of the user running the installation. 5. Malicious installer code can access files, environment variables, credentials, and network resources available to that user. ### Impact Assessment A compromised installer could execute arbitrary code with the installing user's privileges. Depending on the user's environment, this could permit: - Reading or modifying user-owned files. - Accessing environment variables and development credentials. - Modifying local Agent Skill installations. - Making arbitrary outbound network requests. - Establishing persistence where the user's permissi ...[truncated 290 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the installer package to a specific reviewed version, for example `skills@<audited-version>`. 2. Use a lockfile or verified integrity digest where the installation workflow supports it. 3. Identify the expected npm package publisher and registry explicitly. 4. Prefer installation from a signed release or a repository commit pinned by its full immutable commit hash. 5. Make the documented manual-copy method the preferred option when it can operate without executing third-party installer code. 6. Periodically review and update the pinned installer version through a controlled dependency-update process. 7. Advise users not to run the installation command with administrator or root privileges. ]]>
Vulnerability Patterns
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (5)

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding
The README instructs users to run `npx skills add Felo-Inc/felo-skills --skill felo-slides` without pinning a specific package/version. Because `npx` resolves and executes remote package code at install time, a compromised package, typo-squatted dependency, or unexpected upstream update could cause arbitrary code execution on the user's machine during installation.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill instructs use of environment variables and outbound network access to a third-party API, but it does not declare any explicit tool scope such as allowed tools or permissions. This creates an authorization and transparency gap: an agent may invoke capabilities broader than the user or platform expects, increasing the chance of unintended secret access or network actions.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The description says to use the skill whenever users ask to create, make, generate, or export presentations, which is broad enough to trigger on many ordinary requests that may not require this external API workflow. Over-broad invocation can cause unnecessary external data disclosure, unintended API usage, and accidental execution of side effects when the user only wanted advice or local formatting help.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The trigger section includes ambiguous categories like Chinese prompts about making slides and generic English words such as slides, PPT, and presentation deck. These underspecified triggers increase the chance the skill is selected for loosely related conversations, leading to unintended network calls and transmission of user content to the external provider.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The document is primarily written in English, but lines L16 and L22 switch to Chinese for key installation headings. This can create a language/locale policy issue because the skill documentation imposes mixed-language instructions without explicit user opt-in or a documented locale scope.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/run_ppt_task.mjs:192