Back to skill

Security audit

Nutrition Balance Tracker

Security checks for vulnerabilities and agentic risk

Overview

This is a local nutrition-tracking skill with disclosed calculation scripts; I found no hidden network access, persistence, credential handling, or destructive behavior.

Install only if a Chinese-language nutrition report is acceptable and you are comfortable entering food logs plus optional age, sex, height, and weight for local calculation. Treat outputs as rough wellness estimates, not medical advice, especially for clinical conditions or extreme diet goals.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/calculate_targets.js:10
Finding
Missing Numeric and Range Validation Allows Corruption of Nutrition Calculations<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/calculate_targets.js:10-14` - `scripts/calculate_intake.js:26-34` - `scripts/calculate_intake.js:65-66` - `scripts/calculate_burn.js:18-24` **Vulnerability Type**: Improper input validation in health-related calculations **Risk Level**: Medium ### Vulnerable Code #### `scripts/calculate_targets.js:10-14` ```js function calculateBMR({ sex = 'unknown', weight_kg, height_cm, age }) { if (!weight_kg || !height_cm || !age) throw new Error('weight_kg, height_cm, and age are required'); const base = 10 * weight_kg + 6.25 * height_cm - 5 * age; if (sex === 'male') return round(base + 5, 0); if (sex === 'female') return round(base - 161, 0); return round(base - 78, 0); } ``` #### `scripts/calculate_intake.js:26-34` ```js function getWeightGrams(entry, item) { const unit = entry.unit || item.base_unit || 'g'; const amount = Number(entry.amount || entry.quantity || 0); if (unit === 'ml') return amount; if (UNIT_GRAMS[unit]) return amount * UNIT_GRAMS[unit]; if (item.grams_per_unit) return amount * item.grams_per_unit; return amount; } ``` #### `scripts/calculate_intake.js:65-66` ```js const addedWater = waterEntries.reduce((sum, e) => sum + Number(e.water_ml || 0), 0); res.totals.water_ml = round(res.totals.water_ml + addedWater, 1); ``` #### `scripts/calculate_burn.js:18-24` ```js function getExerciseBurn(exercise, weightKg) { const type = exercise.exercise_type || exercise.type; const intensity = exercise.intensity || 'moderate'; const minutes = Number(exercise.duration_min || exercise.duration || 0); const met = (MET[type] && MET[type][intensity]) || 5.0; return round((met * 3.5 * weightKg / 200) * minutes, 0); } ``` ### Technical Analysis The scripts accept profile, food, hydration, and exercise values from JSON input but do not verify that those values are finite numbers within reasonable positive ranges. In `calculate_targets.js`, the condition only checks ...[truncated 2639 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Introduce centralized numeric validation** - Require actual finite numbers, or explicitly parse supported numeric strings. - Reject `NaN`, `Infinity`, and `-Infinity` with `Number.isFinite()`. - Do not rely on truthiness to establish validity. 2. **Enforce reasonable input ranges** - Require positive and physiologically reasonable bounds for age, weight, and height. - Require food quantities and water intake to be nonnegative and capped at documented operational limits. - Require exercise duration to be nonnegative and limited to a reasonable daily maximum. 3. **Reject invalid inputs before calculation** - Return a clear validation error identifying the invalid field. - Avoid silently substituting zero for malformed values. - Validate arrays and each entry before reduction or aggregation. 4. **Prevent non-finite intermediate results** - Verify calculated BMR, target calories, nutrient totals, and exercise burn with `Number.isFinite()` before returning them. - Reject results outside documented calculation limits. 5. **Use a reusable validation helper** ```js function requireFiniteNumber(value, field, { min, max } = {}) { const number = typeof value === 'number' ? value : Number(value); if (!Number.isFinite(number)) { throw new TypeError(`${field} must be a finite number`); } if (min !== undefined && number < min) { throw new RangeError(`${field} must be at least ${min}`); } if (max !== undefined && number > max) { throw new RangeError(`${field} must not exceed ${max}`); } return number; } ``` Apply the helper to all profile measurements, food quantities, hydration values, and exercise durations before performing arithmetic. 6. **Add boundary and malformed-input tests** - Test negative values, zero where prohibited, numeric strings, empty strings, `null`, arrays, objects, invalid text, very large exponents, `NaN`, and infinite values. - Assert that in ...[truncated 84 chars]
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The declared description centers on tracking daily nutrition intake and hydration, logging meals/water/exercise, and judging whether actual intake is balanced relative to goals. The supplied code only calculates recommended targets from a profile using BMR/activity/goal formulas and emits those targets as JSON. While target calculation is related to nutrition guidance, it is only a subset of the declared functionality and not the primary tracking/review behavior described. There are no undeclared sensitive permissions or resource accesses beyond stdin/stdout and local fs read from stdin, but the functional description materially overstates what this code chunk does.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
If confidence is low, explicitly label the result as an estimate and name the main uncertainty source.

## Output Rules

- Prefer practical guidance over theory.
- Do not overwhelm the user with every possible metric.
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
- children or adolescents needing managed nutrition
- post-surgery recovery or clinical nutrition

## Output rules
- label estimates as estimates
- point out the main uncertainty source when input quality is low
- prefer “偏高 / 偏低 / 可调整” over alarmist language
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The markdown instructs the skill to use specific Chinese phrases such as '合理 / 略低 / 偏低 / 略高 / 偏高' and '赤字合理 / 赤字过大 / 盈余合理 / 盈余过大' when presenting results. This imposes a language choice on all users without offering a language preference or explaining a region-specific need, which violates the language/locale policy criteria.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The template hard-codes Chinese headings and output structure for all users without any indication that language should follow user preference or locale. This can cause the agent to ignore the user's requested language, reducing usability and potentially causing misunderstanding of nutrition guidance, though it does not introduce code execution or data exfiltration risk.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The instruction to prefer “偏高 / 偏低 / 可调整” imposes a specific language/locale in outputs. The file does not mention offering the user a language choice or limiting this requirement to a justified region-specific context.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The skill emits natural-language alerts and suggestions exclusively in Chinese, which forces a specific language for user-facing output. This matches the language/locale policy violation category because the file provides no option, configuration, or documented justification for restricting output to Chinese.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
This JSON dataset uses Chinese food names as the canonical keys throughout the file, with English only relegated to aliases. For a general-purpose skill asset, that imposes a specific language/locale choice in the natural-language content without any visible opt-in or justification in this file.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The script hardcodes Chinese status labels and report text throughout the generated output, which enforces a specific language choice for all users. This is a natural-language policy concern because there is no indication of user language selection, opt-in, or documented region-specific justification in the file.

Static analysis

No suspicious patterns detected.