Back to skill

Security audit

Worldly Wisdom

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed decision-analysis workflow with local templates and calculators, though users should treat its numeric helper outputs as advisory and check inputs carefully.

Install only if you want a structured decision-analysis assistant. For legal, medical, financial, market, or otherwise time-sensitive decisions, require fresh evidence or specialist input. If using the bundled calculators, provide your own clean JSON inputs and sanity-check results, especially probabilities, weights, and extreme numeric values.

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

Warning
Location
scripts/decision_matrix.py:45
Finding

Non-Finite Numeric Values Bypass Decision Matrix Validation

Content
View full analysis
float: try: return float(value) except (TypeError, ValueError) as exc: raise InputError(f"Error: {label} must be numeric. Received: {value!r}") from exc def validate(data: dict) -> None: if "weights" not in data or "options" not in data: raise InputError("Error: input JSON must contain 'weights' and 'options'.") weights = data["weights"] options = data["options"] direction = data.get("direction", {}) if not isinstance(weights, dict) or not weights: raise InputError("Error: 'weights' must be a non-empty object.") if not isinstance(options, list) or len(options) < 2: raise InputError("Error: 'options' must contain at least two options.") if not isinstance(direction, dict): raise InputError("Error: 'direction' must be an object if provided.") criteria = list(weights.keys()) names: set[str] = set() weight_total = 0.0 for criterion in criteria: weight_total += _coerce_number(weights[criterion], f"weight for '{criterion}'") if criterion in direction and direction[criterion] not in {"higher", "lower"}: raise InputError( f"Error: direction for '{criterion}' must be 'higher' or 'lower'. Received: {direction[criterion]!r}" ) if weight_total <= 0: raise InputError("Error: weights must sum to a positive number.") ``` ```python def normalise_weights(weights: Dict[str, float]) -> Dict[str, float]: total = sum(float(v) for v in weights.values()) return {k: float(v) / total for k, v in weights.items()} ``` ### Technical Analysis The `_coerce_number()` function treats every value accepted by Python's `float()` as valid. This inc ...[truncated 2182 chars]
Remediation
View remediation
float: try: number = float(value) except (TypeError, ValueError) as exc: raise InputError( f"Error: {label} must be numeric. Received: {value!r}" ) from exc if not math.isfinite(number): raise InputError(f"Error: {label} must be finite. Received: {value!r}") return number ``` 2. Make JSON parsing reject non-standard constants: ```python def _reject_constant(value: str) -> None: raise InputError(f"Error: non-finite JSON number is not allowed: {value}") data = json.loads( path.read_text(encoding="utf-8"), parse_constant=_reject_constant, ) ``` 3. Validate each weight individually. If negative weights are not a supported feature, reject weights below zero rather than checking only the aggregate total. 4. Use the validated numeric values during computation instead of repeatedly calling `float()` on the original untrusted data. 5. Add regression tests for `NaN`, `Infinity`, `-Infinity`, strings representing non-finite numbers, zero-sum weights, and extremely large finite values. 6. Before serialization, assert that every normalized weight, contribution, total, and ranking gap remains finite. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ev_scenarios.py:32
Finding

Non-Finite Numeric Values Bypass Expected-Value Scenario Validation

Content
View full analysis
float: try: return float(value) except (TypeError, ValueError) as exc: raise InputError(f"Error: {label} must be numeric. Received: {value!r}") from exc ``` ```python def validate(data: dict) -> None: if "scenarios" not in data: raise InputError("Error: input JSON must contain 'scenarios'.") scenarios = data["scenarios"] if not isinstance(scenarios, list) or not scenarios: raise InputError("Error: 'scenarios' must be a non-empty list.") total_probability = 0.0 for index, scenario in enumerate(scenarios, start=1): if not isinstance(scenario, dict): raise InputError(f"Error: scenario #{index} must be an object.") for key in ("name", "probability", "value"): if key not in scenario: raise InputError(f"Error: each scenario must include '{key}'.") probability = _coerce_number(scenario["probability"], f"probability for scenario #{index}") if probability < 0 or probability > 1: raise InputError( f"Error: scenario probabilities must be decimals between 0 and 1. Received: {probability!r} for {scenario['name']!r}" ) _coerce_number(scenario["value"], f"value for scenario #{index}") total_probability += probability if abs(total_probability - 1.0) > 1e-6: raise InputError( f"Error: scenario probabilities must sum to 1.0. Received: {total_probability:.6f}." ) def expected_value(scenarios: list[dict]) -> float: return sum(float(s["probability"]) * float(s["value"]) for s in scenarios) ``` ### Technical Analysis The numeric conversion function does not verify that converted values are f ...[truncated 1838 chars]
Remediation
View remediation
float: try: number = float(value) except (TypeError, ValueError) as exc: raise InputError( f"Error: {label} must be numeric. Received: {value!r}" ) from exc if not math.isfinite(number): raise InputError(f"Error: {label} must be finite. Received: {value!r}") return number ``` 2. Configure `json.loads()` to reject `NaN`, `Infinity`, and `-Infinity` through a `parse_constant` rejection callback. 3. Store validated probabilities and values in a normalized structure and use those values for computation rather than converting the original input again. 4. Assert that every contribution and the final expected value are finite before rendering or serialization. 5. Add automated tests covering non-finite probabilities, non-finite payoffs, invalid probability totals, boundary probabilities of zero and one, and very large finite values. 6. Consider limiting numeric magnitude where extreme values would be nonsensical for the declared decision-analysis use case. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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 (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The description promises a rich strategic decision-analysis capability using numerous qualitative reasoning frameworks and update mechanisms. The supplied code only performs a standard weighted decision matrix calculation: validating structured input, normalizing weights and criterion scores, ranking options, and rendering results. While a decision matrix can be a supporting tool for decision analysis, the implemented functionality is far narrower than the declared purpose and omits nearly all named analysis methods. There are no suspicious undeclared external accesses or permissions, but the primary purpose is materially different from the description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The code’s actual behavior is much narrower than the description. It only calculates expected value and a few related metrics from predefined scenarios in a JSON file. While the output note mentions concepts like reversibility and competence, those are not actually analyzed. The declared purpose describes a comprehensive qualitative decision-analysis/oracle skill for many kinds of decisions, but the code does not implement those capabilities. This is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill instructs the agent to read support files and create JSON inputs for bundled scripts, but it does not declare any explicit tool scope or permissions. In clients that rely on manifest-style restrictions, this can lead to over-broad file access or ambiguous authorization boundaries, increasing the chance of unintended reads/writes beyond the skill's intended assets.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger conditions include broad phrases like 'think this through' and 'what am I missing,' which are common in ordinary conversation. Overly generic activation can cause the skill to engage unexpectedly, potentially steering unrelated chats into decision-analysis workflows, requesting unnecessary sensitive context, or invoking file-based helper behavior when the user did not intend it.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The listed trigger examples are everyday phrases that are too ambiguous to safely control activation. In shared or automated environments, this can produce prompt-routing errors, leading the agent to apply the wrong policy, ask for extraneous inputs, or perform unnecessary structured analysis on benign requests.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The compact prompts section explicitly promotes ambiguous phrases as activation cues, which increases the likelihood of unintended invocation across many normal user interactions. Misrouting is more concerning here because the skill encourages structured analysis, possible clarification loops, and optional script/file workflows that may expand the interaction surface beyond what the user expected.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The borderline examples leave activation criteria underspecified for high-stakes decision queries such as refinancing, contract risk, hiring, and market attractiveness. That ambiguity can cause inconsistent triggering, leading the skill to engage on domains where fresher evidence or specialist safeguards may be needed, or fail to engage when decision support was intended.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.