Back to skill

Security audit

Buffer Calculator

Security checks for vulnerabilities and agentic risk

Overview

This skill is not deceptive or exfiltrating data, but it is a safety-relevant lab calculator with serious calculation errors and broader local tool access than its documentation admits.

Review this skill before installing. Do not rely on its buffer recipes for real lab preparation unless the calculation code is corrected and independently validated. If used at all, run it in a restricted workspace, avoid granting Write/Edit or broad shell access, and treat all quantities as draft calculations that must be checked against trusted protocols.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/main.py:57
Finding
Solid-component quantities are inflated by a factor of 1,000<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py`, lines 57–64 **Vulnerability Type**: Incorrect unit conversion in safety-relevant calculations **Risk Level**: High ### Vulnerable Code ```python if unit == "mM": # Calculate grams needed moles = conc * final_volume_ml / 1000 # mmol to mol grams = moles * mw results.append({ "component": component, "amount_mg": round(grams * 1000, 2), "amount_g": round(grams, 3), ``` ### Technical Analysis The conversion from millimolar concentration and milliliter volume is incorrect. Multiplying `mM` by `mL` and dividing by 1,000 produces millimoles, not moles. The value must be divided by 1,000,000 before it can be multiplied by molecular weight in grams per mole. For example, 137 mM NaCl in 1,000 mL should require approximately 8.006 g: ```text 137 mM × 1,000 mL × 58.44 g/mol ÷ 1,000,000 = 8.006 g ``` The implementation instead reports approximately 8,006 g, which is 1,000 times too large. This affects every solid component represented in millimolar units. ### Attack Path 1. A user requests a routine recipe such as 1X PBS. 2. The calculator processes each solid component using the incorrect conversion. 3. Millimoles are treated as moles. 4. The generated mass is inflated by a factor of 1,000. 5. The calculator presents the result as a valid preparation instruction. 6. A user relying on the output may attempt to weigh or use the incorrect quantity. No attacker gains operating-system privileges through this defect. The exploitation path concerns the integrity and safety of laboratory calculations. ### Impact Assessment The defect can generate unusable formulations, cause significant reagent waste, exceed solubility or equipment limits, and expose users to unexpectedly large chemical quantities. It affects all PBS, RIPA, and TAE solid components calculated by the program. The scope is limited to calculation integrity and downstream laboratory activity. ...[truncated 100 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Correct the conversion so that millimolar concentration and milliliter volume are converted to moles: ```python moles = conc * final_volume_ml / 1_000_000 grams = moles * mw ``` Alternatively, calculate millimoles explicitly and convert them to grams: ```python millimoles = conc * final_volume_ml / 1000 grams = millimoles * mw / 1000 ``` Add automated tests using independently verified formulations, including: - 1 L of 1X PBS - 500 mL of 1X RIPA - 1 L of 1X and 10X TAE - Scaling checks confirming that doubling volume doubles every quantity - Unit tests checking both `amount_g` and `amount_mg` For safety-relevant output, include a warning when a calculated quantity is implausibly large relative to the requested final volume. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/main.py:25
Finding
Percentage-based components are calculated without defining stock concentration or percentage basis<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py`, lines 25–26 and 65–72 **Vulnerability Type**: Ambiguous and incorrect concentration calculation **Risk Level**: High ### Vulnerable Code The recipe defines both SDS and Triton X-100 using the same generic percentage unit: ```python "SDS": {"MW": 288.38, "concentration": 0.1, "unit": "%"}, "Triton X-100": {"MW": None, "concentration": 1, "unit": "%"} ``` All percentage components are then treated as pure liquid volumes: ```python elif unit == "%": ml_needed = conc * final_volume_ml / 100 results.append({ "component": component, "amount_ml": round(ml_needed, 2), "concentration": conc, "unit": "%" }) ``` ### Technical Analysis The implementation does not distinguish between weight-per-volume percentages, volume-per-volume percentages, and dilution from a stock solution. Triton X-100 may reasonably be represented as a volume-per-volume percentage. SDS, however, is ordinarily handled as a solid or as a stock solution with a defined concentration. A target of 0.1% SDS could mean: - 0.1% weight per volume, requiring a mass calculation; or - Dilution from a specified stock, such as a 10% weight-per-volume solution. The code always emits an amount in milliliters and does not record the assumed stock strength. For 500 mL of 0.1% SDS, it prints 0.5 mL. If a 10% stock is intended, 5 mL would be required. The documentation contains a 10% stock example that is inconsistent with the implementation. ### Attack Path 1. A user requests a RIPA recipe. 2. The calculator identifies SDS as a generic percentage component. 3. It assumes the percentage can be directly converted to a volume of pure reagent. 4. It emits an amount in milliliters without identifying percentage basis or stock concentration. 5. The user may interpret the quantity as a stock-solution volume. 6. The prepared buffer contains an incorrect SDS concentration. No system privileges are ob ...[truncated 536 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Represent the percentage basis and source form explicitly. For example: ```python "SDS": { "concentration": 0.1, "unit": "%w/v", "source": "stock", "stock_concentration": 10.0, "stock_unit": "%w/v" }, "Triton X-100": { "concentration": 1.0, "unit": "%v/v", "source": "neat" } ``` For stock dilution, use: ```python stock_volume_ml = target_concentration * final_volume_ml / stock_concentration ``` For a solid specified as `% w/v`, calculate mass directly: ```python mass_g = target_percent * final_volume_ml / 100 ``` The output must identify whether an amount refers to a neat reagent, solid mass, or a stock solution of a specified concentration. Reject recipes whose percentage basis or stock strength is undefined. Add tests for 0.1% SDS prepared from a 10% stock and for 1% volume-per-volume Triton X-100. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:43
Finding
Volume and concentration inputs accept negative and non-finite values<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py`, lines 43–44 and 117–120 **Vulnerability Type**: Insufficient numeric input validation **Risk Level**: Medium ### Vulnerable Code The calculation API performs no numeric validation: ```python def calculate(self, buffer_type, final_volume_ml, concentration_x=1.0): """Calculate buffer recipe.""" buffer_type = buffer_type.upper() ``` The command-line parser accepts unrestricted floating-point values: ```python parser.add_argument("--volume", "-v", type=float, default=500, help="Final volume in mL") parser.add_argument("--concentration", "-c", type=float, default=1.0, help="Concentration (X)") ``` ### Technical Analysis Using `type=float` validates only whether Python can parse a floating-point representation. It does not require the value to be positive or finite. Inputs such as negative numbers, zero, `nan`, and `inf` can reach the arithmetic logic. The calculator consequently produces negative, zero, infinite, or NaN reagent quantities and formats them as valid preparation instructions. The `calculate()` API has the same weakness, so fixing only command-line parsing would not protect programmatic callers. ### Attack Path 1. A user or calling process provides an invalid value such as `--volume -500`, `--concentration nan`, or `--volume inf`. 2. `argparse` accepts the value as a Python float. 3. `calculate()` performs arithmetic without checking positivity or finiteness. 4. The result is printed as though it were a valid recipe. 5. An automated workflow or inexperienced user may consume the invalid output. This issue does not grant operating-system privileges. Its impact is confined to output integrity, denial of useful calculation, and unsafe downstream interpretation. ### Impact Assessment Invalid values can corrupt generated preparation plans and propagate non-finite quantities into other software using the Python API. Negative in ...[truncated 310 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Validate values inside `calculate()` so all callers are protected: ```python import math if not isinstance(final_volume_ml, (int, float)): raise TypeError("Final volume must be numeric") if not math.isfinite(final_volume_ml) or final_volume_ml <= 0: raise ValueError("Final volume must be a finite positive value") if not isinstance(concentration_x, (int, float)): raise TypeError("Concentration must be numeric") if not math.isfinite(concentration_x) or concentration_x <= 0: raise ValueError("Concentration must be a finite positive value") ``` Add reasonable upper bounds based on supported laboratory use, or require explicit confirmation for unusually large values. Return a nonzero command-line exit status when validation fails. Add tests for zero, negative values, NaN, positive and negative infinity, extremely large values, and valid decimal inputs. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:4
Finding
Skill declares filesystem modification and unrestricted shell tools beyond its functional requirements<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, line 4 **Vulnerability Type**: Excessive Agent tool permissions **Risk Level**: Medium ### Vulnerable Code ```yaml allowed-tools: [Read, Write, Bash, Edit] ``` ### Technical Analysis The Skill is a local calculation utility whose bundled implementation only needs Python execution and standard output. It does not need to read arbitrary files, write files, or edit files. Granting `Read`, `Write`, `Edit`, and general-purpose `Bash` access violates least-privilege principles. In an Agent environment, unrestricted shell and filesystem tools materially increase the impact of unrelated prompt injection, malicious contextual content, or operator misuse. No evidence was found that the current Skill instructions actively exploit these permissions. The risk arises from exposing capabilities that are unnecessary for the stated task. ### Attack Path 1. The Skill is loaded into an Agent environment with all declared tools enabled. 2. The Agent receives malicious or misleading contextual instructions from another source. 3. Those instructions induce use of `Read`, `Write`, `Edit`, or `Bash`. 4. The Agent can inspect files, alter files, or execute shell commands outside the calculator’s legitimate scope. 5. The resulting impact depends on the host sandbox and the identity under which the Agent tools operate. The project itself contains no command-injection primitive, persistence mechanism, or malicious shell command. Exploitation requires an external instruction source or misuse of the overprivileged Agent context. ### Impact Assessment Potential privileges include reading files accessible to the Agent, modifying or replacing user-accessible files, and executing commands with the Agent process identity. The maximum scope is determined by the host’s sandboxing and operating-system permissions. There is no evidence that the Skill requests elevation to administrator or root privileges. Nevertheless, gen ...[truncated 109 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Remove tools that are unnecessary for recipe calculation. Prefer a narrowly scoped execution permission that can invoke only the bundled calculator. If the platform cannot restrict execution to a specific entry point: - Remove `Read`, `Write`, and `Edit`. - Replace unrestricted `Bash` with the narrowest available Python execution capability. - Run the calculator in a sandbox without network access. - Use a read-only project directory. - Restrict access to user files, credentials, environment secrets, and sensitive directories. - Apply execution time, memory, and process limits. - Document the exact reason for every retained permission. If future output-file functionality is added, grant write access only to a dedicated output directory rather than the general filesystem. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
Granting Bash to a buffer-calculation skill expands the execution surface beyond its stated purpose and enables arbitrary shell command execution if the skill or surrounding agent workflow is abused. Even absent overtly malicious content, unnecessary command execution privileges increase the potential for filesystem tampering, data access, and environment reconnaissance.

Intent-Code Divergence

Medium
Confidence
99% confidence
Finding
The manifest allows Read, Write, Bash, and Edit, but the skill's risk assessment says there is no file access. That inconsistency can conceal the real attack surface from users and reviewers, making it easier for the skill to read or alter local files under the guise of a low-risk calculator.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The documentation claims no file system access even though the manifest grants Read/Write/Edit and the skill explicitly describes generating output files. This misrepresents the skill's capabilities, which can cause users or downstream policy systems to trust the skill more than warranted and allow unintended local file modification or data exposure.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The 'Related Skills' section uses the labels '上游' and '下游' alongside English, which introduces a specific language choice into the skill's natural-language interface. Because the document does not state that multilingual labels are optional or user-selected, this may conflict with a language/locale policy requiring user opt-in.

Static analysis

No suspicious patterns detected.