Back to skill

Security audit

pet-food-calculator

Security checks for vulnerabilities and agentic risk

Overview

This is a pet-feeding calculator with coherent, disclosed behavior, but users should treat its nutrition output cautiously because some advertised features are incomplete and malformed numeric inputs can produce unsafe or invalid results.

Before installing, understand that this is a local helper script, not veterinary advice. Use only realistic positive numeric inputs, review results carefully, and do not rely on it for illness, prescription diets, or unexplained weight changes. Also note that some advertised features are only reference guidance or partial output, not fully implemented automation.

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/pet_food_calculator.py:233
Finding
Insufficient Validation of Numeric Feeding and Cost Parameters<![CDATA[ ## Vulnerability Details **File Location**: `scripts/pet_food_calculator.py:97-98`, `scripts/pet_food_calculator.py:144-150`, and `scripts/pet_food_calculator.py:233-244` **Vulnerability Type**: Improper input validation of numeric parameters **Risk Level**: Medium ### Vulnerable Code Argument definitions accept arbitrary floating-point values: ```python ap.add_argument("--target-weight", type=float, help="ideal/target weight (starts weight-loss plan)") ap.add_argument("--food-calories", type=float, help="metabolizable energy kcal/kg (printed on the bag)") ap.add_argument("--food-price", type=float, help="price of one bag") ap.add_argument("--bag-kg", type=float, help="bag size in kg") ap.add_argument("--adult-weight", type=float, help="expected adult weight for puppies") ``` The supplied food-calorie value is used as a divisor without verifying that it is finite and positive: ```python grams_per_day = food_kcal / (args.food_calories / 1000.0) \ if args.food_calories else None ``` The bag size is also used as a divisor without validation: ```python if args.food_price and args.bag_kg and grams_per_day: monthly_kg = grams_per_day * 30.4 / 1000.0 res["cost"] = { "monthly_kg": round(monthly_kg, 2), "monthly_cost": round(monthly_kg / args.bag_kg * args.food_price, 2), "currency_note": "in the same currency as --food-price", "bag_lasts_days": round(args.bag_kg / monthly_kg * 30.4), } ``` Only current body weight receives an explicit positivity check: ```python if args.weight <= 0: ap.error("--weight must be positive") if args.target_weight and args.target_weight >= args.weight: print("Note: target weight ≥ current weight — no weight-loss plan " "will be generated.", file=sys.stderr) ``` ### Technical Analysis Python's `float` parser accepts negative values, `nan`, `inf`, and `-inf`. The calculator does not consistently reject these va ...[truncated 3006 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a reusable argument parser that rejects non-finite and non-positive values: ```python def positive_finite(value: str) -> float: try: number = float(value) except ValueError as exc: raise argparse.ArgumentTypeError("must be a number") from exc if not math.isfinite(number) or number <= 0: raise argparse.ArgumentTypeError( "must be a finite number greater than zero" ) return number ``` 2. Apply it to every parameter that must be positive: ```python ap.add_argument("--weight", type=positive_finite, required=True) ap.add_argument("--target-weight", type=positive_finite) ap.add_argument("--food-calories", type=positive_finite) ap.add_argument("--food-price", type=positive_finite) ap.add_argument("--bag-kg", type=positive_finite) ap.add_argument("--adult-weight", type=positive_finite) ``` 3. Add realistic domain bounds where appropriate. For example, reject implausible animal weights, food energy densities, bag sizes, and expected adult weights rather than accepting arbitrarily large finite values. 4. Validate relationships between fields before calling `compute()`: - Ensure target weight is biologically plausible. - Clearly distinguish maintenance, weight-loss, and weight-gain requests. - Require `--food-price` and `--bag-kg` together if either is supplied. - Permit `--adult-weight` only for growing dogs, or explicitly document other behavior. 5. Add defensive checks immediately before every division so future refactoring cannot reintroduce zero or non-finite divisors. 6. Configure JSON serialization to reject non-finite values: ```python json.dumps(res, indent=2, allow_nan=False) ``` 7. Add regression tests covering: - Zero and negative values for every numeric parameter. - `nan`, `inf`, and `-inf`. - Extremely small and extremely large finite values. - Invalid ta ...[truncated 213 chars]
Vulnerability Patterns
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (3)

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
The code substantially matches the general theme of pet feeding calculation, including calorie needs, portions, weight-loss planning, cost estimation, and food transition guidance. However, several specific declared capabilities are not implemented: no breed-based logic exists, no body-condition scoring/input exists, no multi-food cost comparison exists, and no multi-pet household scheduling exists. These are material feature gaps relative to the description, so this is a description-behavior mismatch rather than a perfect match.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill advertises executable capabilities implying shell, file read, and file write behavior, but the manifest does not declare any explicit tool scope or permission boundary. This creates an authorization and review gap: a host may grant broader capabilities than users or reviewers expect, increasing the risk of unintended file access, file modification, or command execution if the backing implementation is invoked.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def run(*args):
    return subprocess.run([sys.executable, str(SCRIPT), *args],
                          capture_output=True, text=True)
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.