Back to skill

Security audit

Shipping Calc

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a local shipping calculator, but crafted shipping values can make its script run arbitrary local commands.

Review this skill before installing. It does not show remote fetching, credential access, exfiltration, or persistent backdoors, but its shell script should not be run on untrusted shipment values until the awk argument handling is fixed and numeric inputs are validated. The publisher should also clarify that pricing is not actually zone-based, explain or remove the placeholder track and batch commands, and document what the local data directory contains.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/script.sh:75
Finding

AWK Source Injection Enables Arbitrary Command Execution

Content
View full analysis
" awk "BEGIN{base=5; per_kg=2.5; printf \"Shipping %skg %s->%s: \$%.2f\n\",$2,$3,$4,base+$2*per_kg}" } cmd_compare() { local weight="${2:-}" local from="${3:-}" local to="${4:-}" [ -z "$weight" ] && die "Usage: $SCRIPT_NAME compare " echo 'Standard: '; cmd_rate $2 $3 $4; echo 'Express (2x): '; awk "BEGIN{printf \"\$%.2f\n\",(5+$2*2.5)*2}" } cmd_estimate() { local length="${2:-}" local width="${3:-}" local height="${4:-}" local weight="${5:-}" [ -z "$length" ] && die "Usage: $SCRIPT_NAME estimate " awk "BEGIN{vol=$2*$3*$4/5000; actual=$5; dim=vol>actual?vol:actual; printf \"Billable weight: %.1fkg\n\",dim}" } cmd_duty() { local value="${2:-}" local country="${3:-}" [ -z "$value" ] && die "Usage: $SCRIPT_NAME duty " awk "BEGIN{rate=0.1; printf \"Duty estimate for \$%s to %s: \$%.2f\n\",$2,$3,$2*rate}" } ``` ### Technical Analysis The command-line arguments are expanded directly into double-quoted AWK program strings. They are therefore interpreted as AWK source code rather than treated exclusively as data. An attacker who controls one of the affected arguments can insert AWK syntax that terminates the intended expression and introduces additional statements. AWK provides the `system()` function, allowing injected AWK code to execute operating-system commands. Although the functions assign arguments to local variables, those variables are not used safely. Direct references such as `$2`, `$3`, and `$4` are concatenated into executable AWK source. The issue affects the `rate`, ...[truncated 1486 chars]
Remediation
View remediation
%s: $%.2f\n", weight, from, to, base + weight * per_kg }' ``` 3. Validate numeric fields before invoking AWK. For example, reject empty, negative, non-finite, and non-numeric weights, dimensions, and declared values. 4. Validate the exact argument count for each command before accessing any argument. 5. Quote all shell expansions, including arguments passed between functions. 6. Use the already defined local variables instead of positional parameters inside AWK construction. 7. Add regression tests using AWK metacharacters, quotes, semicolons, braces, newlines, and `system()` payloads to confirm that all supplied values remain data. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
" echo 'Batch processing $2' } ``` ```bash case "$cmd" in rate) shift; cmd_rate "$@" ;; compare) shift; cmd_compare "$@" ;; estimate) shift; cmd_estimate "$@" ;; duty) shift; cmd_duty "$@" ;; track) shift; cmd_track "$@" ;; batch) shift; cmd_batch "$@" ;; ``` ### Technical Analysis The dispatcher removes the command name using `shift` before passing the remaining arguments to each handler. Consequently, the first documented argument is available as `$1`. However, every handler ...[truncated 2118 chars]:75
Finding

Incorrect Argument Handling Causes Command Failure and Misleading Behavior

Content
View full analysis
" awk "BEGIN{base=5; per_kg=2.5; printf \"Shipping %skg %s->%s: \$%.2f\n\",$2,$3,$4,base+$2*per_kg}" } cmd_compare() { local weight="${2:-}" local from="${3:-}" local to="${4:-}" [ -z "$weight" ] && die "Usage: $SCRIPT_NAME compare " echo 'Standard: '; cmd_rate $2 $3 $4; echo 'Express (2x): '; awk "BEGIN{printf \"\$%.2f\n\",(5+$2*2.5)*2}" } cmd_estimate() { local length="${2:-}" local width="${3:-}" local height="${4:-}" local weight="${5:-}" [ -z "$length" ] && die "Usage: $SCRIPT_NAME estimate " awk "BEGIN{vol=$2*$3*$4/5000; actual=$5; dim=vol>actual?vol:actual; printf \"Billable weight: %.1fkg\n\",dim}" } cmd_duty() { local value="${2:-}" local country="${3:-}" [ -z "$value" ] && die "Usage: $SCRIPT_NAME duty " awk "BEGIN{rate=0.1; printf \"Duty estimate for \$%s to %s: \$%.2f\n\",$2,$3,$2*rate}" } cmd_track() { local number="${2:-}" [ -z "$number" ] && die "Usage: $SCRIPT_NAME track " echo 'Tracking $2: check carrier website' } cmd_batch() { local file="${2:-}" [ -z "$file" ] && die "Usage: $SCRIPT_NAME batch " echo 'Batch processing $2' } ``` ```bash case "$cmd" in rate) shift; cmd_rate "$@" ;; compare) shift; cmd_compare "$@" ;; estimate) shift; cmd_estimate "$@" ;; duty) shift; cmd_duty "$@" ;; track) shift; cmd_track "$@" ;; batch) shift; cmd_batch "$@" ;; ``` ### Technical Analysis The dispatcher removes the command name using `shift` before pass ...[truncated 2132 chars]
Remediation
View remediation
" local weight="$1" local from="$2" local to="$3" # Perform validated calculation using the named variables. } ``` 4. Quote all argument forwarding: ```bash cmd_rate "$weight" "$from" "$to" ``` 5. Replace single-quoted placeholder output with safe, explicit formatting where output is intended: ```bash printf 'Tracking %s: check carrier website\n' "$number" ``` 6. Implement actual tracking and batch processing only if those features are intended. Otherwise, remove the commands or clearly identify them as unsupported placeholders in `SKILL.md`. 7. For batch processing, validate that the path is a permitted regular file, prevent unintended special-file handling, and parse each record as data rather than executable shell input. 8. Add tests covering every documented invocation, missing and excessive arguments, whitespace in arguments, malformed numeric values, and expected command output. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The code is broadly related to shipping estimation, including rate, compare, dimensional-weight, and duty commands, so the overall domain is aligned. However, the declared description specifically says zone-based rates, while the implementation uses a fixed base plus per-kg formula with no zone logic. In addition, the script exposes extra capabilities—tracking and batch processing—that are not declared. These are not just internal implementation details; they are user-facing commands. No suspicious external access or undeclared permissions are evident beyond creating a local data directory. Therefore this is a description/behavior mismatch, though not a severe one.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest and top-level description at L04 and L11 constrain the skill to calculating shipping costs and duty estimates. However, the documented track and batch commands add capabilities for tracking shipments and processing files, which are materially broader than estimating shipping costs.

Content

No source excerpt is available for this finding.

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
80% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · scripts/script.sh (reported line 9)May include surrounding context.

sh
DATA_DIR="$HOME/.local/share/shipping-calc"
mkdir -p "$DATA_DIR"

#
#
#
#

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest claims zone-based shipping rates, but cmd_rate computes cost using only a fixed base plus per-kilogram multiplier and merely prints the origin/destination values. The from and to inputs do not affect pricing, so the behavior does not match the advertised zone-based calculation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes a skill for calculating shipping costs with zone-based rates and duty estimates, but the code also exposes track and batch commands. Tracking shipments and generic batch processing extend the skill beyond the stated estimation-focused purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file states that data is stored in ~/.local/share/shipping-calc/, which is a behavior that can affect user data and privacy. The description does not explain what is stored, how long it is kept, or whether users can clear it, so the disclosure is incomplete.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.