Back to skill

Security audit

Co2 Tank Monitor

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed CO2 tank monitoring helper with some reliability and overbroad permission caveats, but no hidden, destructive, or data-stealing behavior was found.

Install only if you understand this is a lightweight monitoring aid, not a validated safety system. Scope any cron jobs, sensor-log reads, and alert integrations yourself; avoid granting unnecessary Write/Edit access where your platform allows narrower permissions; and validate pressure, consumption, and capacity assumptions before relying on reports for real lab operations.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:27
Finding
Unvalidated Numeric Inputs Can Crash or Disable Automated Monitoring<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py`, lines 27–35; related command-line input handling at lines 153–182 **Vulnerability Type**: Improper numeric input validation and unhandled arithmetic exceptions **Risk Level**: Medium ### Vulnerable Code ```python def calculate_remaining_days(pressure: float, daily_consumption: float) -> float: """Calculate remaining days""" if daily_consumption <= 0: return float('inf') return pressure / daily_consumption def calculate_depletion_time(remaining_days: float) -> datetime: """Calculate estimated depletion time""" return get_current_time() + timedelta(days=remaining_days) ``` The command-line arguments are parsed as unrestricted floating-point values: ```python parser.add_argument( "--pressure", "-p", type=float, default=8.0, help="Current tank pressure (MPa), default 8.0" ) parser.add_argument( "--daily-consumption", "-d", type=float, default=1.5, help="Daily consumption rate (MPa/day), default 1.5" ) parser.add_argument( "--alert-days", "-a", type=int, default=2, help="Alert threshold in days, default 2" ) ``` ### Technical Analysis The program does not verify that pressure and consumption values are finite, positive, and within physically reasonable limits. Python's `float()` parser accepts special values such as `nan`, `inf`, and `-inf`. A zero or negative consumption value is converted to positive infinity by `calculate_remaining_days()`. That value is then passed to `timedelta(days=remaining_days)`, which can raise `OverflowError` or another arithmetic conversion exception. Non-finite or excessively large pressure values can produce the same result. Negative pressure and negative alert thresholds are also accepted, potentially producing misleading status calculations rather than a sensor-data validation failure. No exception handler converts these failures into an explicit monitoring-error alert. ### Att ...[truncated 1252 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Validate all numeric values immediately after argument parsing. - Use `math.isfinite()` to reject `nan`, positive infinity, and negative infinity. - Require pressure and daily consumption to be positive and within documented physical limits. - Require `alert_days` to be non-negative and impose a reasonable maximum. - Do not translate invalid consumption into infinity; report invalid sensor data explicitly. - Catch `OverflowError`, `ValueError`, and related calculation failures at the command boundary. - Return a dedicated monitoring-failure exit code that automation treats as an urgent operational fault. - Add tests covering zero, negative, non-finite, and excessively large values. Example hardening: ```python import math def validate_inputs(pressure: float, daily_consumption: float, alert_days: int) -> None: if not math.isfinite(pressure) or pressure < 0 or pressure > 20: raise ValueError("Pressure must be finite and between 0 and 20 MPa") if not math.isfinite(daily_consumption) or daily_consumption <= 0: raise ValueError("Daily consumption must be finite and greater than zero") if alert_days < 0 or alert_days > 30: raise ValueError("Alert threshold must be between 0 and 30 days") ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:164
Finding
Cylinder Capacity Is Accepted and Reported but Ignored by the Prediction Model<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py`, lines 164–185; related simulation logic at lines 18–24 **Vulnerability Type**: Safety-relevant parameter ignored during calculation **Risk Level**: Medium ### Vulnerable Code The application accepts only the documented 10 L and 40 L capacities: ```python parser.add_argument( "--capacity", "-c", type=int, default=40, choices=[10, 40], help="Tank capacity (L), default 40" ) ``` However, the prediction omits the selected capacity: ```python # Get data if args.simulate: pressure, capacity, daily_consumption = simulate_sensor_data() else: pressure = args.pressure capacity = args.capacity daily_consumption = args.daily_consumption # Calculate remaining_days = calculate_remaining_days(pressure, daily_consumption) depletion_time = calculate_depletion_time(remaining_days) ``` The same issue applies to simulated capacity values: ```python def simulate_sensor_data(): """Simulate sensor data reading""" # Simulate 40L cylinder, full pressure ~15MPa, working pressure 8-10MPa, alarm pressure ~2MPa pressure = round(random.uniform(2.5, 12.0), 2) capacity = random.choice([10, 40]) daily_consumption = round(random.uniform(0.5, 3.0), 2) return pressure, capacity, daily_consumption ``` ### Technical Analysis The selected cylinder capacity is carried into the formatted report but never affects `remaining_days`. Consequently, identical pressure and consumption inputs produce identical depletion estimates for 10 L and 40 L cylinders. This conflicts with the Skill documentation, which presents capacity as a supported prediction parameter and describes materially different expected durations for those cylinder sizes. Displaying the selected capacity in the report may create the impression that it was incorporated into the calculation. Whether capacity should be applied directly depends on the physical meaning and calibration of the consumption v ...[truncated 1285 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Define a physically valid, unit-consistent prediction model before incorporating capacity. - Clarify whether `daily_consumption` represents pressure loss per day for the specific cylinder or an absolute gas-volume consumption rate. - If consumption is measured in an absolute volume unit, incorporate cylinder capacity and pressure using an appropriate conversion model. - If consumption is already calibrated as pressure loss per day for each cylinder, remove the implication that capacity independently affects the estimate. - Either remove `--capacity` from the calculation interface or label it as report-only metadata. - Add tests proving the intended relationship between 10 L and 40 L cylinder predictions. - Update the documentation so examples and stated duration tables match the implemented model. - Add a warning when capacity and consumption assumptions are inconsistent or have not been calibrated for the selected cylinder. ]]>

T05 · Unauthorized Access and Privilege Escalation

Note
Location
SKILL.md:4
Finding
Declared Tool Permissions Exceed the Skill's Functional Requirements<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, line 4 **Vulnerability Type**: Excessive tool authorization and violation of least privilege **Risk Level**: Low ### Vulnerable Code ```yaml allowed-tools: [Read, Write, Bash, Edit] ``` ### Technical Analysis The implemented monitor calculates values from command-line arguments or locally generated simulation data and prints a report. Its executable code does not require general-purpose file modification through `Write` or `Edit`. Although script execution may require a command-execution facility, unrestricted `Bash` is broader than the narrow capability needed to invoke `scripts/main.py`. Declaring unnecessary tools increases the potential impact of malicious or untrusted context processed while the Skill is active. The reviewed package does not itself misuse these permissions. The risk arises from granting capabilities beyond the legitimate requirements of the monitoring task. ### Attack Path 1. The Skill is loaded in an agent environment that enforces or exposes the declared tools. 2. The current task includes attacker-controlled or otherwise untrusted instructions. 3. Those instructions induce the agent to perform an unrelated file modification or shell command. 4. The broadly declared `Write`, `Edit`, or `Bash` capability permits the action even though it is not necessary for CO2 depletion calculation. 5. Depending on the host platform's sandbox and user privileges, files accessible to the agent could be modified or arbitrary local commands could be executed. ### Impact Assessment No privilege escalation is implemented directly in the reviewed files. The attainable scope depends entirely on the host's interpretation of `allowed-tools`, sandbox boundaries, and operating-system identity. If these declarations confer effective access, potential impact includes modification of files writable by the agent and execution of commands with the agent process's existing privileges. There is n ...[truncated 141 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove `Write` and `Edit` because the current implementation does not require file modification. - Replace unrestricted `Bash` with a narrowly scoped script-execution permission where supported. - Restrict execution to the packaged `scripts/main.py` entry point and approved arguments. - If the platform cannot scope shell access, document that limitation and enforce an external command allowlist or sandbox. - Keep `Read` only if the operational workflow genuinely requires reading sensor files; the current executable accepts values through command-line arguments. - Review tool declarations whenever functionality changes and grant only the minimum capabilities required for the active task. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Description-Behavior Mismatch

Medium
Confidence
85% confidence
Finding
The documented behavior includes cron-based automation, log-file reads, and execution flows using external sensor data, which materially exceed the manifest description of an IoT monitoring simulation. This scope mismatch is risky because users may grant tools and deploy the skill in more privileged operational contexts than expected, enabling unintended file access, scheduled execution, and integration into production workflows without appropriate review.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
The documentation explicitly shows operational automation via subprocess execution and external alert hooks such as `send_urgent_alert()` and `send_notification()`. Even though this is presented as example code, it expands the skill from passive monitoring/simulation into active orchestration, which can trigger unintended actions or be reused unsafely in environments where sensor input, paths, or alert integrations are not tightly controlled.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The markdown includes natural-language labels '上游' and '下游' alongside English terms. Because the skill otherwise appears to target general users and does not state any locale requirement or provide an explicit language preference mechanism, this can conflict with a language/locale policy requiring user opt-in.

Static analysis

No suspicious patterns detected.