Back to skill

Security audit

Ynab Api

Security checks for vulnerabilities and agentic risk

Overview

This YNAB skill appears purpose-aligned, but it needs Review because it can read and write a live budget while being declared prompt-only and triggered by broad finance requests.

Install only if you intentionally want an agent to access your YNAB account and potentially create transactions or transfers. Prefer environment variables or a protected config file, verify the skill only contacts the official YNAB API, require confirmation before any write action, and be careful with generic finance requests because the skill may activate even when you did not explicitly mention YNAB.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/transfer.sh:50
Finding

Unsafe JSON Construction in Authenticated Financial Transactions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/transfer.sh:38
Finding

jq Program Injection Through Untrusted Search and Account Names

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/transfer.sh:19
Finding

Insufficient Validation of Transaction-Critical Amounts and Dates

Content
View full analysis
&2 echo "Example: $0 abc123 'Savings' 100.50 2026-02-21 'Monthly savings'" >&2 exit 1 fi YNAB_API="https://api.ynab.com/v1" # Convert euros to milliunits (negative for outbound transfer) AMOUNT_MILLIUNITS=$(echo "$AMOUNT_EUROS * -1000" | bc | cut -d. -f1) ``` From `scripts/ynab-helper.sh:63-75`: ```bash read -p "Account ID (or press Enter for default): " ACCOUNT_ID if [ -z "$ACCOUNT_ID" ]; then ACCOUNT_ID=$(jq -r '.default_account_id // .accounts[0]' "$CONFIG_FILE") fi read -p "Date (YYYY-MM-DD, default today): " DATE DATE="${DATE:-$(date +%Y-%m-%d)}" read -p "Amount (negative for expense): " AMOUNT AMOUNT_MILLI=$((AMOUNT * 1000)) read -p "Payee name: " PAYEE read -p "Category ID: " CATEGORY_ID read -p "Memo (optional): " MEMO ``` ### Technical Analysis The scripts verify only that certain arguments are nonempty. They do not enforce: - A strict numeric representation for amounts. - Expected sign semantics. - Reasonable minimum or maximum amounts. - Decimal precision. - A valid calendar date. - Valid account or category identifier formats. `transfer.sh` always multiplies the supplied amount by `-1000`. Supplying a negative amount therefore reverses the intended direction. Arbitrary calculator expressions are also passed to `bc`, which can cause unexpected values or resource consumption. `ynab-helper.sh` uses Bash integer arithmetic, despite prompting for a general amount. Decimal values s ...[truncated 1310 chars]
Remediation
View remediation
&2 exit 1 fi AMOUNT_MILLIUNITS=$( awk -v amount="$AMOUNT_EUROS" 'BEGIN { printf "%.0f\n", amount * -1000 }' ) ``` Further hardening should include: 1. Reject zero and enforce a documented maximum amount. 2. Require positive input for `transfer.sh`, because the script determines the outbound sign. 3. Clearly support decimal amounts in `ynab-helper.sh` rather than using Bash integer arithmetic. 4. Validate dates with both a regex and a calendar round trip. 5. Validate identifiers against expected UUID syntax or confirm that they exist in the authenticated API response. 6. Confirm that source and destination accounts are different. 7. Present the source, destination, normalized date, and exact milliunit amount for explicit confirmation before submission. 8. Use an import ID or duplicate check to reduce accidental repeated transactions. ]]>

other

Warning
Location
skill.toml:97
Finding

Runtime Metadata Understates Executable and Financial Capabilities

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (44)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The description claims a full-featured YNAB management skill that can add transactions, create transfers, track goals, monitor spending, and generate reports, and says it should be used for a wide range of finance intents such as 'add an expense' or 'upcoming bills'. The actual code only implements one narrow capability: a scheduled, read-only daily budget check/report. It accesses YNAB budget/month and scheduled transaction data and formats a morning summary, but contains no write operations, no transaction creation, no transfer support, and no general-purpose interaction handling. While parts of the description related to spending analysis, goal tracking, Age of Money, and budget reports are consistent, the declared scope materially overstates the implemented behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The code is clearly YNAB-related and does support one declared capability: adding transactions, plus limited spending lookup. However, the description substantially overstates the skill’s scope. The script does not implement goal tracking, transfers, budget reports, Age of Money, upcoming bills, or general personal-finance management. Its actual behavior is a small CLI helper around a few YNAB endpoints, not a full-featured budget management skill matching the broad trigger guidance. There are no obvious undeclared malicious capabilities, but there is a material description-versus-behavior mismatch due to the claimed breadth of functionality.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The invocation guidance is extremely broad, telling the system to use this skill whenever the user mentions general budgeting or personal finance, even without naming YNAB. In context, this is dangerous because the skill includes write-capable financial actions such as adding transactions and creating transfers, so over-triggering can cause unintended access to financial data or accidental state-changing operations.

Content

No source excerpt is available for this finding.

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-guide.md (reported line 100)May include surrounding context.

md
| Accounts | `GET /v1/budgets/{id}/accounts` |
| Categories | `GET /v1/budgets/{id}/categories` |
| Transactions | `GET/POST /v1/budgets/{id}/transactions` |
| Single transaction | `GET/PUT/DELETE /v1/budgets/{id}/transactions/{id}` |
| Month summary | `GET /v1/budgets/{id}/months/current` |
| Scheduled | `GET /v1/budgets/{id}/scheduled_transactions` |
| Payees | `GET /v1/budgets/{id}/payees` |

Scope Creep

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest advertises a prompt-only skill with no tools or capabilities, yet the embedded instructions direct use of curl, jq, local config files, environment variables, and a remote API. This mismatch can bypass platform safety gating and mislead orchestrators into invoking a skill that expects network access, credential handling, and filesystem interaction without explicit declaration.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger language is extremely broad, covering generic phrases like 'add an expense', 'how much did I spend', and 'check my budget' even when YNAB is not mentioned. In context, this is risky because the skill supports financial record modification, so over-triggering could route unrelated finance requests into a workflow that assumes access to a live personal budget and may prompt or perform sensitive actions.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · README.md (reported line 3)May include surrounding context.

md
# YNAB API Skill for Claude Code

Manage your [YNAB](https://www.ynab.com/) budget directly from Claude Code. Add transactions, track goals, monitor spending, create transfers, and generate reports.

## Installation

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill declares shell-capable behavior but does not define any explicit tool scope such as allowed tools or permissions. That creates an authorization gap where the agent may invoke shell functionality more broadly than intended, increasing the chance of unintended command execution or access to sensitive local data and environment variables.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
76% confidence
Finding

The skill encourages broad reuse across ongoing personal-finance interactions, which increases the chance that sensitive budget context, account identifiers, or prior transaction assumptions persist across requests. In a financial-management context, over-retention or over-application of session context can lead to mistaken actions, privacy leakage, or unauthorized use of stale financial state.

Content

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

md
---
name: ynab-api
description: "YNAB (You Need A Budget) budget management via API. Add transactions, track goals, monitor spending, create transfers, and generate budget reports. Use this skill whenever the user mentions YNAB, budget tracking, spending analysis, budget goals, Age of Money, or wants to manage their personal finances -- even if they just say 'add an expense', 'how much did I spend', 'check my budget', or 'upcoming bills' without naming YNAB explicitly. Also use for automated budget reports and financial summaries."
user-invocable: true
metadata: {"requiredEnv": ["YNAB_API_KEY", "YNAB_BUDGET_ID"]}
---

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The skill is designed to send budget and transaction data to an external service endpoint, which is a real external-transmission behavior. In context this is expected for a YNAB integration, but it still carries confidentiality risk because personal financial data and API credentials are involved, and accidental invocation or overbroad use could expose sensitive information to the third-party API.

Content

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

Common API Operations

bash
YNAB_API="https://api.ynab.com/v1"

# Add a transaction
# POST \/budgets/\/transactions

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Several guidance and troubleshooting lines are written as mandatory instructions in Italian, including 'riprovare silenziosamente' and 'NON assumere subito', without offering the user a language choice or documenting a justified locale restriction. This creates a natural-language policy issue because the skill imposes a specific language/locale in its operational instructions without opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill instructs users to configure a live YNAB API token and use scripts that can create transactions and transfers, but it does not clearly warn that these operations affect a real budget. In a personal-finance skill, silent state-changing behavior increases the risk of unintended financial record modification, duplicate entries, or accidental transfers if the agent invokes scripts without explicit confirmation.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
77% confidence
Finding

The skill recommends persistent storage of the API key in ~/.config/ynab/config.json, which creates session/credential persistence on disk. While common, this becomes a security issue if the file is left world-readable, synced insecurely, or exposed via backups or local compromise, especially because the token can authorize modifications to financial records.

Content

Scanner excerpt · prompt_context.md (reported line 7)May include surrounding context.

Configuration

Set environment variables YNAB_API_KEY and YNAB_BUDGET_ID, or create ~/.config/ynab/config.json:

json
{

Session Persistence

Medium
Category
Rogue Agent
Confidence
82% confidence
Finding

The script supports long-lived storage of an API key in a local JSON file under ~/.config/ynab/config.json, which can expose sensitive financial API credentials if file permissions are weak, the host is shared, or backups/logging capture the file. In the context of a finance skill, compromise of this token could allow unauthorized access to budget and transaction data and potentially modification via the API.

Content

Scanner excerpt · scripts/daily-budget-check.sh (reported line 13)May include surrounding context.

sh
API_KEY=$(jq -r .api_key "${YNAB_CONFIG:-$HOME/.config/ynab/config.json}")
  BUDGET_ID=$(jq -r '.budget_id // "last-used"' "${YNAB_CONFIG:-$HOME/.config/ynab/config.json}")
else
  echo "Error: YNAB config not found. Set YNAB_API_KEY+YNAB_BUDGET_ID or create ~/.config/ynab/config.json" >&2
  exit 1
fi

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
exit 1
fi

YNAB_API="https://api.ynab.com/v1"
TODAY=$(date -u '+%Y-%m-%d')
TOMORROW=$(date -u -d "+1 day" '+%Y-%m-%d')
END_7_DAYS=$(date -u -d "+7 days" '+%Y-%m-%d')

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
exit 1
fi

YNAB_API="https://api.ynab.com/v1"
TODAY=$(date -u '+%Y-%m-%d')
TOMORROW=$(date -u -d "+1 day" '+%Y-%m-%d')
END_7_DAYS=$(date -u -d "+7 days" '+%Y-%m-%d')

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/daily-budget-check.sh (reported line 17)May include surrounding context.

sh
exit 1
fi

YNAB_API="https://api.ynab.com/v1"
TODAY=$(date -u '+%Y-%m-%d')
TOMORROW=$(date -u -d "+1 day" '+%Y-%m-%d')
END_7_DAYS=$(date -u -d "+7 days" '+%Y-%m-%d')

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/daily-spending-report.sh (reported line 37)May include surrounding context.

sh
exit 1
fi

YNAB_API="https://api.ynab.com/v1"
TODAY=$(date -u '+%Y-%m-%d')
TOMORROW=$(date -u -d "+1 day" '+%Y-%m-%d')
END_7_DAYS=$(date -u -d "+7 days" '+%Y-%m-%d')

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/goals-progress.sh (reported line 20)May include surrounding context.

sh
exit 1
fi

YNAB_API="https://api.ynab.com/v1"
TODAY=$(date -u '+%Y-%m-%d')
TOMORROW=$(date -u -d "+1 day" '+%Y-%m-%d')
END_7_DAYS=$(date -u -d "+7 days" '+%Y-%m-%d')

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/month-comparison.sh (reported line 19)May include surrounding context.

sh
exit 1
fi

YNAB_API="https://api.ynab.com/v1"
TODAY=$(date -u '+%Y-%m-%d')
TOMORROW=$(date -u -d "+1 day" '+%Y-%m-%d')
END_7_DAYS=$(date -u -d "+7 days" '+%Y-%m-%d')

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/scheduled-upcoming.sh (reported line 20)May include surrounding context.

sh
exit 1
fi

YNAB_API="https://api.ynab.com/v1"
TODAY=$(date -u '+%Y-%m-%d')
TOMORROW=$(date -u -d "+1 day" '+%Y-%m-%d')
END_7_DAYS=$(date -u -d "+7 days" '+%Y-%m-%d')

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/setup-automation.sh (reported line 33)May include surrounding context.

sh
exit 1
fi

YNAB_API="https://api.ynab.com/v1"
TODAY=$(date -u '+%Y-%m-%d')
TOMORROW=$(date -u -d "+1 day" '+%Y-%m-%d')
END_7_DAYS=$(date -u -d "+7 days" '+%Y-%m-%d')

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/transfer.sh (reported line 31)May include surrounding context.

sh
exit 1
fi

YNAB_API="https://api.ynab.com/v1"
TODAY=$(date -u '+%Y-%m-%d')
TOMORROW=$(date -u -d "+1 day" '+%Y-%m-%d')
END_7_DAYS=$(date -u -d "+7 days" '+%Y-%m-%d')

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/ynab-helper.sh (reported line 18)May include surrounding context.

sh
exit 1
fi

YNAB_API="https://api.ynab.com/v1"
TODAY=$(date -u '+%Y-%m-%d')
TOMORROW=$(date -u -d "+1 day" '+%Y-%m-%d')
END_7_DAYS=$(date -u -d "+7 days" '+%Y-%m-%d')

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · skill.toml (reported line 57)May include surrounding context.

toml
exit 1
fi

YNAB_API="https://api.ynab.com/v1"
TODAY=$(date -u '+%Y-%m-%d')
TOMORROW=$(date -u -d "+1 day" '+%Y-%m-%d')
END_7_DAYS=$(date -u -d "+7 days" '+%Y-%m-%d')