Back to skill

Security audit

Shelter

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate read-only finance skill, but it needs review because its install docs and API endpoint override can expose users to avoidable credential and supply-chain risk.

Install only from the package identity you intend to trust, verify the npm package name before using the README command, and keep SHELTER_API_URL unset unless you are deliberately using a trusted HTTPS Shelter endpoint. Treat all API responses and /v1/ask prompts as confidential financial data, and rotate the Shelter API key if it may have been sent to an unexpected endpoint.

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

Warning
Location
SKILL.md:67
Finding
API Credential Can Be Redirected to an Arbitrary Host## Vulnerability Details **File Location**: `SKILL.md:67-68` **Additional Locations**: `SKILL.md:27, 93-94, 123-124, 144-145, 166-167, 187-188, 211-214, 239-240, 263-264, 284-287, 331-332` **Vulnerability Type**: Unvalidated credential-bearing endpoint override **Risk Level**: Medium ### Vulnerable Code ```bash curl -s -H "X-Shelter-Key: $SHELTER_API_KEY" \ "${SHELTER_API_URL:-https://api.shelter.money/agent}/v1/status" ``` The same endpoint override pattern is used for all documented API requests. ### Technical Analysis The Skill sends the sensitive `SHELTER_API_KEY` value in an HTTP header to a base URL controlled by the `SHELTER_API_URL` environment variable. The value is not validated, restricted to the expected `api.shelter.money` hostname, or required to use HTTPS. If an attacker can influence the agent's environment, shell configuration, process launcher, or project-specific environment settings, the attacker can set `SHELTER_API_URL` to a server under their control. The next Skill request will then disclose the API key in the `X-Shelter-Key` header. An `http://` value could additionally expose the key in plaintext to network observers. ### Attack Path 1. An attacker influences the environment in which the agent runs and sets `SHELTER_API_URL` to an attacker-controlled URL, such as `https://attacker.example/collect`. 2. The user asks the agent to check financial status, runway, alerts, or another Shelter function. 3. The agent executes the documented `curl` command. 4. `curl` sends `X-Shelter-Key: $SHELTER_API_KEY` to the attacker-controlled server. 5. The attacker captures the API key and uses it against the legitimate Shelter API, subject to the key's assigned scopes and rate limits. ### Impact Assessment Successful exploitation exposes the user's Shelter API credential. The attacker could access the financial information allowed by that key, potentially including balances, safe-to-spend amounts, e ...[truncated 409 chars]
Remediation
## Remediation Suggestions 1. Remove the endpoint override for normal use and hardcode the trusted endpoint: ```bash SHELTER_API_URL="https://api.shelter.money/agent" ``` 2. If custom endpoints are required for development, validate the parsed URL before attaching the API key: - Require the `https:` scheme. - Require an exact hostname allowlist, such as `api.shelter.money`. - Reject embedded credentials, unexpected ports, redirects to other hosts, and malformed URLs. 3. Configure `curl` to reject insecure transport and unsafe redirects. Do not forward the credential across cross-origin redirects. 4. Separate development credentials from production credentials and require an explicit development mode before permitting a non-production endpoint. 5. Document that users should rotate the API key immediately if an unexpected `SHELTER_API_URL` value may have been used. 6. Apply narrowly scoped API permissions and short credential lifetimes to reduce the impact of disclosure.

T08 · Insecure Dependencies

Warning
Location
README.md:15
Finding
README Installation Command References a Different npm Package## Vulnerability Details **File Location**: `README.md:15-21` **Related Location**: `package.json:2, 24-27` **Vulnerability Type**: Package identity mismatch and dependency-confusion exposure **Risk Level**: Medium ### Vulnerable Code The installation documentation states: ```bash # Claude Code marketplace /plugin marketplace add nextauralabs/shelter-skill # npm npm install -g @shelter/agent-skill # ClawHub clawhub install shelter ``` However, the audited artifact identifies itself under a different npm package name and defines automatic lifecycle scripts: ```json { "name": "@shelter.money/agent-skill", "scripts": { "postinstall": "node install-skill.js", "preuninstall": "node uninstall-skill.js" } } ``` ### Technical Analysis The README instructs users to install `@shelter/agent-skill`, while the audited package is named `@shelter.money/agent-skill`. Consequently, following the documented npm command does not necessarily install the reviewed artifact. npm packages can execute lifecycle scripts during installation. If the differently named package is unrelated, compromised, or attacker-controlled, its installation scripts can run code with the privileges of the user executing npm. The audit does not establish the ownership or current contents of `@shelter/agent-skill`; the confirmed defect is that the documentation directs users away from the package represented by this artifact. ### Attack Path 1. A user follows the npm installation command in `README.md`. 2. npm resolves `@shelter/agent-skill` instead of the audited `@shelter.money/agent-skill`. 3. npm downloads the package associated with that different identity. 4. Any lifecycle scripts declared by the resolved package can execute automatically during installation. 5. If that package is malicious or later becomes compromised, its scripts can execute arbitrary actions under the installing user's account. ### Impac ...[truncated 626 chars]
Remediation
## Remediation Suggestions 1. Replace the documented command with the exact audited package identity: ```bash npm install -g @shelter.money/agent-skill ``` 2. Verify that the intended npm organization and package are controlled by the publisher before releasing corrected documentation. 3. Keep package names consistent across `README.md`, `package.json`, marketplace metadata, release automation, and support documentation. 4. Pin or prominently document the expected version and provide package integrity or provenance information where practical. 5. Add an automated release check that compares every documented npm installation command with the `name` field in `package.json`. 6. Consider npm provenance signing and protected publisher accounts to reduce supply-chain compromise risk.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (22)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description is about a read-only personal finance skill using bank data via Plaid. The supplied code does not implement any financial analysis, data access, coaching, or read-only bank connectivity. Instead, it performs a local filesystem operation to remove the Shelter skill directory. That is a materially different purpose and introduces an undeclared capability: recursive deletion of local files. This is not merely a supporting detail of financial functionality; it is an installer-management action unrelated to the declared end-user behavior.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README markets the skill as an AI financial advisor connected to real bank data, but it does not clearly and prominently warn that user questions and account-derived financial context will be sent to Shelter's external service for processing. Because the data involved is highly sensitive financial information, insufficient disclosure can lead to unintentional sharing of private information with a third party.

Session Persistence

Medium
Category
Rogue Agent
Content
## Get started

1. **Create your free account** at **[shelter.money](https://shelter.money)**
2. **Connect your bank** — takes ~60 seconds via Plaid
3. **Generate an API key** in the app under Settings > API Keys
4. **Install the skill** (pick one):
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.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The README encourages users to ask the agent broadly about 'anything about your money' and lists a wide range of financial tasks without defining clear invocation boundaries or data-minimization expectations. In a skill that connects to real bank-derived data and external AI-backed services, this can cause agents to over-invoke the skill for sensitive financial queries and disclose more contextual data than users may reasonably expect.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill handles banking and spending information via external API calls, including free-form questions sent to Guardian AI, but the description does not prominently warn that sensitive financial context and user queries are transmitted to third-party services. Lack of clear disclosure can prevent informed consent and increase privacy and compliance risk for users sharing personal financial details.

External Transmission

Medium
Category
Data Exfiltration
Content
Every request needs two things:

- **Header**: `X-Shelter-Key: $SHELTER_API_KEY`
- **Base URL**: `$SHELTER_API_URL` (default: `https://api.shelter.money/agent`)

All examples below use these variables. Confirm they're set before making any call.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Every request needs two things:

- **Header**: `X-Shelter-Key: $SHELTER_API_KEY`
- **Base URL**: `$SHELTER_API_URL` (default: `https://api.shelter.money/agent`)

All examples below use these variables. Confirm they're set before making any call.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Every request needs two things:

- **Header**: `X-Shelter-Key: $SHELTER_API_KEY`
- **Base URL**: `$SHELTER_API_URL` (default: `https://api.shelter.money/agent`)

All examples below use these variables. Confirm they're set before making any call.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Every request needs two things:

- **Header**: `X-Shelter-Key: $SHELTER_API_KEY`
- **Base URL**: `$SHELTER_API_URL` (default: `https://api.shelter.money/agent`)

All examples below use these variables. Confirm they're set before making any call.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Every request needs two things:

- **Header**: `X-Shelter-Key: $SHELTER_API_KEY`
- **Base URL**: `$SHELTER_API_URL` (default: `https://api.shelter.money/agent`)

All examples below use these variables. Confirm they're set before making any call.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Every request needs two things:

- **Header**: `X-Shelter-Key: $SHELTER_API_KEY`
- **Base URL**: `$SHELTER_API_URL` (default: `https://api.shelter.money/agent`)

All examples below use these variables. Confirm they're set before making any call.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Every request needs two things:

- **Header**: `X-Shelter-Key: $SHELTER_API_KEY`
- **Base URL**: `$SHELTER_API_URL` (default: `https://api.shelter.money/agent`)

All examples below use these variables. Confirm they're set before making any call.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Every request needs two things:

- **Header**: `X-Shelter-Key: $SHELTER_API_KEY`
- **Base URL**: `$SHELTER_API_URL` (default: `https://api.shelter.money/agent`)

All examples below use these variables. Confirm they're set before making any call.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Every request needs two things:

- **Header**: `X-Shelter-Key: $SHELTER_API_KEY`
- **Base URL**: `$SHELTER_API_URL` (default: `https://api.shelter.money/agent`)

All examples below use these variables. Confirm they're set before making any call.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Every request needs two things:

- **Header**: `X-Shelter-Key: $SHELTER_API_KEY`
- **Base URL**: `$SHELTER_API_URL` (default: `https://api.shelter.money/agent`)

All examples below use these variables. Confirm they're set before making any call.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Every request needs two things:

- **Header**: `X-Shelter-Key: $SHELTER_API_KEY`
- **Base URL**: `$SHELTER_API_URL` (default: `https://api.shelter.money/agent`)

All examples below use these variables. Confirm they're set before making any call.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
**When NOT to use**: User wants day-by-day detail (use forecast instead).

```bash
curl -s -H "X-Shelter-Key: $SHELTER_API_KEY" \
  "${SHELTER_API_URL:-https://api.shelter.money/agent}/v1/runway"
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
**Topics**: `debt`, `savings`, `bills`, `subscriptions`, `negotiation`, `general`

```bash
curl -s -H "X-Shelter-Key: $SHELTER_API_KEY" \
  "${SHELTER_API_URL:-https://api.shelter.money/agent}/v1/coach/advice?topic=debt"
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
curl -s -X POST -H "X-Shelter-Key: $SHELTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"question": "What should I prioritize right now?"}' \
  "${SHELTER_API_URL:-https://api.shelter.money/agent}/v1/ask"
```

**Key response fields**:
Confidence
82% confidence
Finding
Unlike the structured endpoints, `/v1/ask` sends free-form financial questions to an AI-backed service, which can include arbitrarily sensitive personal or account-derived context. Without a strong warning, minimization guidance, or explicit consent language, users may unknowingly transmit more sensitive data than necessary to external AI processing systems.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The Security section says the API returns 'no raw bank data,' but the documented endpoints expose highly sensitive account-derived financial information such as balances, commitments, merchant insights, anomalies, and forecast details. This can mislead users or integrators into underestimating the sensitivity of the data being transmitted and stored, resulting in weaker handling, disclosure, or consent practices.

Vague Triggers

Low
Confidence
84% confidence
Finding
This is a manifest file, so vague-trigger review applies. The description "Your AI financial advisor, connected to your real bank data" is broad promotional language that does not constrain when or for what requests the skill should be invoked, which can contribute to overly broad matching in systems that use manifest descriptions for routing.

Natural-Language Policy Violations

Low
Confidence
61% confidence
Finding
The only applicable SQP-3 subcategory here is language or locale policy violations, and this file does not clearly force a language or locale. However, no direct language/locale policy violation is present, so this should not be treated as a finding under SQP-3.

Static analysis

No suspicious patterns detected.