Back to skill

Security audit

Crucible Forge

Security checks for vulnerabilities and agentic risk

Overview

This skill is not clearly malicious, but it needs review because it runs broad local workspace analysis and executable Python configs while overstating its safety guarantees.

Review before installing or running. Use only configs you wrote or fully reviewed, do not run it with elevated privileges, avoid untrusted workspaces or symlinks, verify backups independently before moving files, and treat generated plans/audits as advisory rather than proof of zero data loss.

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

T09 · Insecure Skill Coding Practices

Error
Location
forge_plan.py:297
Finding
Reorganization plans are generated without enforcing the required backup<![CDATA[ ## Vulnerability Details **File Location**: `forge_plan.py:297-337`, `forge_plan.py:374-393` **Vulnerability Type**: Missing security-control enforcement **Risk Level**: High ### Vulnerable Code ```python def generate_plan(config, scan_report: dict) -> dict: """Generate complete reorganization plan.""" print("Generating safety rules...") safety_rules = generate_safety_rules(config, scan_report) print("Planning directory creation...") dirs = generate_directory_creation(config) print("Generating _README.md content...") readmes = generate_readmes(config) print("Planning file moves...") moves = generate_moves(config, scan_report, safety_rules) print("Building execution order...") execution_order = build_execution_order(moves, safety_rules) print("Validating plan...") issues = validate_plan(moves, safety_rules, scan_report) plan = { "generated_at": datetime.now().isoformat(), "workspace_root": getattr(config, "WORKSPACE_ROOT", "."), "safety_rules": safety_rules, "directories_to_create": dirs, "readmes_to_generate": readmes, "moves": moves, "execution_order": execution_order, "validation_issues": issues, "summary": { "directories_to_create": len(dirs), "readmes_to_generate": len(readmes), "files_to_move": len(moves), "reference_patches": sum(len(m.get("reference_updates", [])) for m in moves), "validation_errors": len([i for i in issues if i["severity"] in ("ERROR", "CRITICAL")]), "validation_warnings": len([i for i in issues if i["severity"] == "WARNING"]), }, "rollback_command": ( "# To rollback, restore from the pre-move backup:\n" f"# tar -xzf backups/forge-pre-move-*.tar.gz -C {getattr(config, 'WORKSPACE_ROOT', '.')}\n" "# Then verify with: python3 forge_audit.py --config forge_config.py --phase ...[truncated 2096 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Enforce backup verification before calling `generate_moves()` whenever `REQUIRE_BACKUP_BEFORE_PLAN` is enabled. 2. Fail closed if the backup directory is missing, no recent archive exists, or archive validation fails. 3. Require evidence of a successful pre-audit, such as a signed or integrity-protected audit result tied to the current workspace snapshot. 4. Verify that the backup: - Is a regular, non-symlink file. - Is readable and non-empty. - Has a supported archive format. - Passes archive integrity checks. - Contains the expected workspace root and critical protected files. 5. Return a nonzero exit status and do not write a plan when the requirement is unsatisfied. 6. Add automated tests confirming that plan generation is rejected when backups are absent, stale, corrupt, or unrelated. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
forge_audit.py:224
Finding
Generated audit artifacts can mask missing workspace files<![CDATA[ ## Vulnerability Details **File Location**: `forge_audit.py:224-230`, `forge_audit.py:249-269`, `forge_audit.py:357-363` **Vulnerability Type**: Incorrect integrity verification **Risk Level**: High ### Vulnerable Code ```python # Check 6: Create manifest print(" Creating file manifest...") manifest = create_manifest(workspace_root) manifest_dir = getattr( config, "AUDIT_DIR", os.path.join(workspace_root, "backups") ) os.makedirs(manifest_dir, exist_ok=True) manifest_path = os.path.join( manifest_dir, f"pre_manifest_{int(time.time())}.json" ) with open(manifest_path, "w") as f: json.dump(manifest, f, indent=2) ``` ```python current_manifest = create_manifest(workspace_root) current_count = len(current_manifest) if manifest_path and os.path.exists(manifest_path): with open(manifest_path) as f: pre_manifest = json.load(f) pre_count = len(pre_manifest) if current_count >= pre_count: result.check_pass( "File count", f"Pre: {pre_count}, Post: {current_count} (no files lost)" ) else: lost = pre_count - current_count result.check_fail( "File count", f"Pre: {pre_count}, Post: {current_count} — {lost} files MISSING" ) pre_paths = {e["path"] for e in pre_manifest} current_paths = {e["path"] for e in current_manifest} missing = pre_paths - current_paths if missing: for m in sorted(missing)[:20]: result.check_fail("Missing file", m) ``` ```python audit_dir = getattr( config, "AUDIT_DIR", os.path.join(workspace_root, "backups") ) os.makedirs(audit_dir, exist_ok=True) post_manifest_path = os.path.join( audit_dir, f"post_manifest_{int(time.time())}.json" ) with open(post_manifest_path, "w") as f: json.dump(current_manifest, f, indent=2) result.check_pass("Post-manifest created", post_manifest_path) ``` ### Technical Analysis The pre-move ...[truncated 1636 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Exclude `AUDIT_DIR`, `OUTPUT_DIR`, `BACKUP_DIR`, and all Forge-generated artifacts from both pre- and post-move snapshots. 2. Always compute the set difference between baseline paths and current paths, regardless of aggregate file counts. 3. Compare expected source-to-destination move mappings rather than requiring paths to remain unchanged. 4. Verify content hashes so that replacement of a deleted file with an unrelated file cannot satisfy the integrity check. 5. Store audit manifests outside `WORKSPACE_ROOT`, or collect the baseline only after creating and explicitly excluding audit artifacts. 6. Record symlink type, inode or stable identity where supported, size, and cryptographic hash. 7. Fail the audit for every unexplained missing baseline object, even when the post-move count is greater. 8. Add regression tests covering deletion plus creation of an unrelated file and deletion masked by generated audit artifacts. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
forge_audit.py:272
Finding
Post-move audit does not detect deleted protected files<![CDATA[ ## Vulnerability Details **File Location**: `forge_audit.py:272-290` **Vulnerability Type**: Incomplete protected-file integrity validation **Risk Level**: High ### Vulnerable Code ```python # Check 3: Protected files unchanged protected_files = getattr(config, "PROTECTED_FILES", []) if manifest_path and os.path.exists(manifest_path): with open(manifest_path) as f: pre_manifest = json.load(f) pre_hashes = {e["path"]: e["hash"] for e in pre_manifest} import glob as glob_mod for pf in protected_files: matches = glob_mod.glob(os.path.join(workspace_root, pf)) for m in matches: rel = str(Path(m).relative_to(workspace)) current_hash = get_file_hash(m) pre_hash = pre_hashes.get(rel, "") if pre_hash and current_hash == pre_hash: result.check_pass(f"Protected unchanged: {rel}") elif pre_hash: result.check_fail( f"Protected CHANGED: {rel}", "Hash mismatch — file was modified!" ) else: result.check_warn( f"Protected file: {rel}", "Not in pre-manifest" ) ``` ### Technical Analysis Protected paths are expanded only against the post-move filesystem. If a protected file has been deleted or moved, `glob.glob()` returns no matches and the inner validation loop never executes. No failure or warning is recorded for that configured protected path. The pre-manifest already contains the information needed to detect this condition, but the implementation does not preserve the set of protected files that matched before the move and does not compare that set with post-move matches. This is a fail-open integrity check: the complete absence of a protected file bypasses the hash comparison intended to protect it. ### Attack Path 1. Configure a critical file, such as `MEMORY.md`, in `PROTECTED_FILES`. ...[truncated 810 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. During pre-audit, expand every protected-file pattern and store the exact matched path set separately in the manifest. 2. During post-audit, require every previously matched protected path to: - Still exist. - Be a regular file of the expected type. - Remain at its expected path unless an explicitly approved mapping exists. - Match its original cryptographic hash. 3. Treat a protected pattern that matched before but matches nothing afterward as a hard failure. 4. Decide and document whether a protected pattern that never matched should be a warning or failure; critical explicit paths should fail. 5. Reject protected paths that escape the workspace after normalization. 6. Add tests for deleted, renamed, replaced, truncated, and symlink-substituted protected files. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
forge_scan.py:82
Finding
Workspace symlinks allow reads outside the configured workspace boundary<![CDATA[ ## Vulnerability Details **File Location**: `forge_scan.py:82-89`, `forge_scan.py:104-111`, `forge_scan.py:211-220`; `forge_audit.py:125-143`, `forge_audit.py:441-448` **Vulnerability Type**: Symlink-based workspace boundary bypass **Risk Level**: High ### Vulnerable Code ```python for fn in filenames: fp = root_path / fn try: stat = fp.stat() files.append({ "path": str(fp.relative_to(workspace)), "size": stat.st_size, "modified": stat.st_mtime, "extension": fp.suffix.lower(), "protected": False, }) except OSError: pass ``` ```python filepath = workspace / f["path"] try: content = filepath.read_text(encoding="utf-8", errors="replace") except OSError: continue ``` ```python for f in files: if f["size"] > max_size: continue filepath = workspace / f["path"] try: content = filepath.read_text(encoding="utf-8", errors="replace") except OSError: continue ``` ```python def get_file_hash(filepath: str) -> str: """SHA-256 hash of a file.""" h = hashlib.sha256() try: with open(filepath, "rb") as f: for chunk in iter(lambda: f.read(8192), b""): h.update(chunk) return h.hexdigest() except OSError: return "" ``` ```python for fn in filenames: fp = Path(root) / fn if fp.stat().st_size > 10 * 1024 * 1024: continue try: content = fp.read_text(encoding="utf-8", errors="replace") for pat in compiled: if pat.search(content): exposed.append(str(fp.relative_to(workspace))) break except OSError: pass ``` ### Technical Analysis The scanner and auditor derive a lexical path under `WORKSPACE_ROOT`, but then use `Path.stat()`, `Path.read_text()`, and `open()` without checking whether the final resolved path remains inside the configured workspace. These operatio ...[truncated 1882 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use `lstat()` to identify symlinks before reading or hashing files. 2. Default to skipping symlinks and emit an explicit audit warning that identifies the link without opening its target. 3. If symlinks must be supported, resolve each candidate with `Path.resolve(strict=True)` and verify: ```python resolved == workspace or workspace in resolved.parents ``` 4. Perform the containment check immediately before opening the file to reduce time-of-check/time-of-use exposure. 5. On supported platforms, use descriptor-based access with no-follow protections such as `O_NOFOLLOW`, and validate the opened descriptor's file type. 6. Apply the same boundary check consistently in inventory, reference scanning, secrets scanning, manifest hashing, protected-file checks, and content auditing. 7. Avoid running Forge with elevated privileges. 8. Add tests for links to files outside the workspace, chained symlinks, broken links, and links replaced concurrently during scanning. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
forge_audit.py:160
Finding
Backup validation accepts empty, corrupt, unrelated, or non-regular archive entries<![CDATA[ ## Vulnerability Details **File Location**: `forge_audit.py:160-177` **Vulnerability Type**: Insufficient backup authenticity and integrity validation **Risk Level**: Medium ### Vulnerable Code ```python if os.path.isdir(backup_dir): backups = [] for f in os.listdir(backup_dir): fp = os.path.join(backup_dir, f) if f.endswith((".tar.gz", ".tgz", ".zip")): backups.append((fp, os.path.getmtime(fp))) if backups: newest = max(backups, key=lambda x: x[1]) age = time.time() - newest[1] if age < max_age: result.check_pass( "Backup exists and recent", f"{newest[0]} ({age/3600:.1f}h old)" ) else: result.check_warn( "Backup exists but stale", f"{newest[0]} ({age/3600:.1f}h old)" ) else: result.check_fail( "No backup archives found", f"Checked {backup_dir}" ) else: result.check_fail("Backup directory missing", backup_dir) ``` ### Technical Analysis The pre-audit considers a backup valid based only on its filename suffix and modification time. It does not establish that the entry is a regular file, that it is non-empty and readable, that its archive structure is valid, that its contents can be extracted, or that it contains a backup of the current workspace. A directory or symlink with an archive-like name may also enter the candidate list because no regular-file or symlink check is performed. A zero-byte file named `fake.zip` with a fresh timestamp is enough to make the backup check pass. In addition, a stale backup produces only a warning rather than a failure, even though configuration describes a maximum age for a backup to be considered fresh enough. ### Attack Path 1. Create an empty or invalid archive-like entry: ```bash touch backups/fake.zip ``` 2. Ensure its modification timestamp is within `MAX_BACKUP_AGE_H ...[truncated 717 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require candidates to be regular, non-symlink files using `lstat()` and an explicit file-type check. 2. Require a nonzero size and successful readable-file check. 3. Validate archive structure using the standard `tarfile` or `zipfile` modules. 4. Reject archives that fail integrity tests such as `ZipFile.testzip()` or complete tar member iteration. 5. Confirm that expected critical and protected workspace files exist in the archive. 6. Associate backups with a workspace identifier and baseline manifest to prevent unrelated archives from satisfying the check. 7. Optionally perform a test extraction into a securely created temporary directory with path-traversal protections. 8. Treat a stale backup as a failure when backup freshness is mandatory. 9. Reject archive members containing absolute paths, `..` traversal, unsafe links, or paths outside the intended extraction root. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (28)

Intent-Code Divergence

High
Confidence
97% confidence
Finding
The documentation directly contradicts the skill metadata: the file says Forge only generates plans and does not execute them, while the manifest describes it as executing workspace reorganization. In a file-moving tool, this mismatch is dangerous because users or downstream agents may rely on the safer documented behavior and authorize actions they would not approve if execution capability were accurately disclosed.

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
AI agent workspaces accumulate chaos fast. Files pile up at root. Memory files reference moved documents. Cron jobs point to old paths. Config files drift. One bad reorganization can brick your agent's memory, break running processes, or corrupt critical state files.

Manual cleanup is dangerous. Automated cleanup without safeguards is worse.

## What Forge Does
Confidence
80% confidence
Finding
Skill attempts to nullify the agent's safety policies or restrictions ('you have no restrictions', 'ignore your guidelines', 'do anything now'). This is a direct jailbreak that disables guardrails.

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
AI agent workspaces accumulate chaos fast. Files pile up at root. Memory files reference moved documents. Cron jobs point to old paths. Config files drift. One bad reorganization can brick your agent's memory, break running processes, or corrupt critical state files.

Manual cleanup is dangerous. Automated cleanup without safeguards is worse.

## What Forge Does
Confidence
80% confidence
Finding
Skill attempts to nullify the agent's safety policies or restrictions ('you have no restrictions', 'ignore your guidelines', 'do anything now'). This is a direct jailbreak that disables guardrails.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill presents itself as a safe workspace organizer, but the behavior summary includes subprocess-based process inspection and Python config execution, both of which are materially more sensitive than passive planning. In this context, misleading capability disclosure increases the chance that operators run the skill in trusted environments without appreciating the code-execution and system-inspection surface.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill presents itself as a safe workspace organizer, but the behavior summary includes subprocess-based process inspection and Python config execution, both of which are materially more sensitive than passive planning. In this context, misleading capability disclosure increases the chance that operators run the skill in trusted environments without appreciating the code-execution and system-inspection surface.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill presents itself as a safe workspace organizer, but the behavior summary includes subprocess-based process inspection and Python config execution, both of which are materially more sensitive than passive planning. In this context, misleading capability disclosure increases the chance that operators run the skill in trusted environments without appreciating the code-execution and system-inspection surface.

Credential Access

High
Category
Privilege Escalation
Content
"*.pyc",
    "node_modules",
    "venv",
    ".env",
]

# =============================================================================
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The tool loads the supplied config by importing and executing an arbitrary Python file via `spec.loader.exec_module(config)`. Because `--config` is user-provided, any code in that file runs with the auditor's privileges before auditing begins, enabling arbitrary code execution, file tampering, secret exfiltration, or persistence.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The planner imports and executes the user-supplied Python config via importlib and exec_module, which runs arbitrary code during planning. In this skill context, config files may come from the workspace or other users, so a malicious config can achieve code execution immediately, before any planning safeguards apply.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
],
    }

    return rules


def classify_file(filepath: str, config) -> str:
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Intent-Code Divergence

Medium
Confidence
80% confidence
Finding
The file states Forge has no content understanding and classifies files only by metadata, yet the broader skill description claims it can verify everything works afterward. That creates an overstatement of assurance: a tool that does not understand file semantics or runtime behavior cannot reliably verify functional correctness after reorganization, which may mislead users into trusting incomplete validation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- **Never deletes files.** Moves only. If something looks like garbage, it goes to archive.
- **Never modifies protected files.** You define what's protected; Forge won't touch them.
- **Backup before changes.** Forge refuses to generate a plan without a verified backup.
- **Human reviews the plan.** Forge doesn't auto-execute. You read the plan, you decide.
- **Rollback for every step.** Every move in the plan includes how to undo it.

### Zero-Deletion Policy
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- **Never deletes files.** Moves only. If something looks like garbage, it goes to archive.
- **Never modifies protected files.** You define what's protected; Forge won't touch them.
- **Backup before changes.** Forge refuses to generate a plan without a verified backup.
- **Human reviews the plan.** Forge doesn't auto-execute. You read the plan, you decide.
- **Rollback for every step.** Every move in the plan includes how to undo it.

### Zero-Deletion Policy
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- **Never deletes files.** Moves only. If something looks like garbage, it goes to archive.
- **Never modifies protected files.** You define what's protected; Forge won't touch them.
- **Backup before changes.** Forge refuses to generate a plan without a verified backup.
- **Human reviews the plan.** Forge doesn't auto-execute. You read the plan, you decide.
- **Rollback for every step.** Every move in the plan includes how to undo it.

### Zero-Deletion Policy
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill advertises capabilities that clearly require file read, file write, and shell/process inspection, yet it declares no explicit tool scope or permission boundaries. In an agent ecosystem, missing scope metadata can cause the skill to run with broader privileges than users expect, increasing the chance of unsafe file operations or command execution.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Content
This skill loads configuration from a user-provided Python file using `importlib.exec_module`. **This executes the config file as Python code.**

- Only run config files you have written or fully reviewed
- A malicious or unreviewed config file can execute arbitrary code on your system
- Config path is validated for existence, `.py` extension, and size (1MB cap) before execution
- Do not run configs provided by untrusted sources without inspection
Confidence
98% confidence
Finding
The skill explicitly states that it loads a user-provided Python config file with importlib.exec_module, which executes that file as code. This is a direct arbitrary code execution primitive: any attacker who can influence the config file can run commands, exfiltrate data, alter files, or persist on the host under the agent's privileges.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The comment claims path validation makes config loading secure, but the code still executes the config file contents. This misleading assurance increases the chance that maintainers or users will trust untrusted config files, masking the arbitrary code execution risk and making exploitation more likely in practice.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The code executes the Python config immediately with no explicit warning, consent prompt, or user-facing indication that `--config` is treated as code rather than data. In a workspace-management skill, users may reasonably provide or reuse config files from repositories or generated artifacts, making silent code execution especially risky.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# Check 5: Running processes
    try:
        ps = subprocess.run(["ps", "aux"], capture_output=True, text=True, timeout=10)
        ws_procs = [l for l in ps.stdout.splitlines() if workspace_root in l]
        if ws_procs:
            result.check_warn(
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# Check 5: Running processes
    try:
        ps = subprocess.run(["ps", "aux"], capture_output=True, text=True, timeout=10)
        ws_procs = [l for l in ps.stdout.splitlines() if workspace_root in l]
        if ws_procs:
            result.check_warn(
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The code executes the config file without any explicit user-facing warning that loading the config will run Python code. This increases the chance that users treat a config as inert data and open the planner on an attacker-controlled file, leading to unexpected code execution.

Context-Inappropriate Capability

Medium
Confidence
99% confidence
Finding
load_config imports and executes a Python file with exec_module, which means any code in the config runs immediately. For a workspace-analysis skill, this is especially dangerous because users may point the tool at untrusted repositories or generated configs, turning configuration loading into arbitrary code execution before scanning even begins.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The scanner executes arbitrary local commands from configuration via PROCESS_CHECK_COMMANDS. In an agent skill context, config may be attacker-controlled or untrusted workspace content, so running those commands grants code execution on the host during a seemingly harmless scan operation.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
for cmd in commands:
        try:
            cmd_list = shlex.split(cmd) if isinstance(cmd, str) else list(cmd)
            result = subprocess.run(
                cmd_list, capture_output=True, text=True, timeout=10
            )
            for line in result.stdout.splitlines():
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Scope Creep

Low
Category
Excessive Agency
Content
**USE AT YOUR OWN RISK.**

- The author(s) are NOT liable for any damages, losses, or consequences arising from 
  the use or misuse of this software — including but not limited to financial loss, 
  data loss, security breaches, business interruption, or any indirect/consequential damages.
- This software does NOT constitute financial, legal, trading, or professional advice.
- Users are solely responsible for evaluating whether this software is suitable for
Confidence
70% confidence
Finding
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Static analysis

No suspicious patterns detected.