Back to skill

Security audit

LYGO Protocol Stack Operator

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a disclosed LYGO operator/orientation package, but it needs Review because it overstates its security capabilities and directs users toward mutable installs and unverified local code execution.

Install only if you trust the publisher and are prepared to review the referenced external stack and companion skills yourself. Pin ClawHub and Git versions where possible, set `LYGO_STACK_ROOT` explicitly, do not treat the P0 gate as malware detection, and do not run upload, publish, docker, or worker-loop commands unless you intentionally approved that action and reviewed what data or code will be used.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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

Warning
Location
scripts/lygo_p0_gate.py:65
Finding

File-size limit is enforced only after the entire file is loaded into memory

Content
View full analysis
dict: if len(data) > MAX_BYTES: return { "verdict": "QUARANTINE", "phi_risk": round4(PHI_MAX), "risk": 1.0, "hash16": hashlib.sha256(data).hexdigest()[:16], } ``` ```python for arg in sys.argv[1:]: path = Path(arg) if not path.is_file(): print(f"SKIP not file: {path}") continue data = path.read_bytes() r = validate_bytes(data) ``` ### Technical Analysis The documented 8192-byte limit is checked by `validate_bytes()` only after `Path.read_bytes()` has loaded the entire file into memory. Consequently, `MAX_BYTES` limits only the data accepted by the scoring algorithm; it does not limit filesystem reads or memory allocation. An attacker who can persuade a user or agent to scan an attacker-controlled file can provide a very large regular or sparse file. The Python process will attempt to allocate enough memory for the complete contents before returning the intended `QUARANTINE` verdict. ### Attack Path 1. An attacker supplies or identifies a very large file as an input that should be checked. 2. The user or agent follows the documented workflow and runs `lygo_p0_gate.py` against it. 3. `path.read_bytes()` attempts to load the complete file. 4. The process consumes excessive memory, may be terminated by the operating system, or affects other workloads. 5. The size check and quarantine response are never reached if the allocation or read fails first. ### Impact Assessment This issue does not grant additional privileges or directly execute attacker-controlled code. Its scope is the local process and potentially the host's available memory. Successful exploitation can cause denial of service ...[truncated 92 chars]
Remediation
View remediation
MAX_BYTES: return quarantine_result ``` - Handle `OSError`, memory-related failures, and files that change while being read. - If a hash of oversized files is required, calculate it incrementally in bounded chunks rather than loading the complete file. - Add regression tests using large and sparse files to verify bounded memory usage. ]]>

other

Error
Location
scripts/lygo_p0_gate.py:74
Finding

P0 scoring thresholds make quarantine unreachable for all in-limit files

Content
View full analysis
f32(ENTROPY_HIGH): risk = f32(risk + f32(0.30)) elif ent < f32(ENTROPY_LOW): risk = f32(risk + f32(0.15)) if comp > f32(COMP_POOR): risk = f32(risk + f32(0.25)) risk = f32(min(risk, f32(1.0))) size_damp = f32(f32(float(len(data))) / f32(128.0)) if len(data) < 128 else f32(1.0) phi_risk = f32(risk * f32(PHI_MAX) * size_damp) if phi_risk < f32(PHI_MIN): verdict = "AMPLIFY" elif phi_risk <= f32(PHI_MAX): verdict = "SOFTEN" else: verdict = "QUARANTINE" if ent < f32(ENTROPY_LOW) and verdict == "AMPLIFY": verdict = "SOFTEN" ``` ### Technical Analysis For files no larger than `MAX_BYTES`, the largest possible risk increment is: - `0.30` for high entropy; and - `0.25` for poor compression. The maximum possible `risk` is therefore `0.55`. Because `size_damp` cannot exceed `1.0`, the maximum `phi_risk` is approximately: ```text 0.55 × 1.618 × 1.0 = 0.8899 ``` The code assigns `QUARANTINE` only when `phi_risk` exceeds `PHI_MAX`, which is `1.618`. That condition is mathematically unreachable for every input of 8192 bytes or less. Such files can only receive `AMPLIFY` or `SOFTEN`. The documentation recommends using this gate before executing unknown files. Entropy and repetition measurements do not establish whether content is malicious, and the unreachable quarantine threshold adds false assurance to this workflow. ### Attack Path 1. An attacker creates a malicious script or other active payload no larger than 8192 bytes. 2. The payload is submitted as an unknown file to the documented P0 workflow. 3. The scoring function calculates a maximum `phi_risk` below the quarantine threshold. 4. The gate returns `AMPLIFY` or `SOFTEN`, reg ...[truncated 818 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
scripts/stack_healthcheck.py:13
Finding

Healthcheck executes scripts from an unverified auto-discovered repository

Content
View full analysis
Path | None: env = os.environ.get("LYGO_STACK_ROOT") if env: p = Path(env) if (p / "stack" / "lygo_stack.py").is_file(): return p candidates = [ SKILL_ROOT.parent.parent / "lygo-protocol-stack", Path.home() / "lygo-protocol-stack", Path.cwd() / "lygo-protocol-stack", ] for c in candidates: if (c / "stack" / "lygo_stack.py").is_file(): return c return None ``` ```python checks = [ ("P0 demo", [sys.executable, str(root / "tools" / "run_p0_demo.py"), "--quiet", "--id", "json_minimal"]), ("Stack demo", [sys.executable, str(root / "tools" / "run_full_stack_demo.py")]), ] ok = 0 for name, cmd in checks: if not cmd[1] or not Path(cmd[1]).is_file(): print(f" SKIP {name} (script missing)") continue r = subprocess.run(cmd, cwd=root, capture_output=True, text=True, timeout=120) ``` ### Technical Analysis The healthcheck treats the existence of `stack/lygo_stack.py` as sufficient proof that a directory is a trusted LYGO checkout. It searches locations influenced by the environment, home directory, and current working directory, then executes Python files from the selected directory. The code does not validate: - Repository origin or remote URL. - A pinned commit or release. - Cryptographic signatures or file hashes. - Directory ownership and permissions. - Whether symbolic links redirect files outside the expected checkout. - Whether the user explicitly selected and approved the discovered directory. Although argument arrays prevent shell metacharacter injection, they do not make the selected Python source trustworthy. ### Attack Path 1. An attacker creates or modifies a directory na ...[truncated 1104 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
README.md:6
Finding

Documented workflows install and execute mutable, unpinned remote dependencies

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documentation claims integrator/operator capabilities that are not substantiated by the actual code behavior described in the finding. In a security-sensitive skill, overstating functionality can mislead operators into assuming audits, filters, or network controls exist when they do not, reducing defense-in-depth.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documentation claims integrator/operator capabilities that are not substantiated by the actual code behavior described in the finding. In a security-sensitive skill, overstating functionality can mislead operators into assuming audits, filters, or network controls exist when they do not, reducing defense-in-depth.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding

The README instructs users to run npx clawhub@latest install ..., which fetches and executes the latest published package version at runtime rather than a pinned, reviewed release. If the upstream package is compromised, hijacked, or publishes a malicious update, users following the documentation could execute attacker-controlled code on their systems.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill documents shell execution, file access, environment-variable usage, package installation, git clone, docker, and publish flows, but does not declare an explicit tool scope or permissions boundary. This makes it easier for an agent runtime or human operator to over-grant capabilities, increasing the risk of unintended command execution or access to sensitive local resources.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

Using npx clawhub@latest pulls whatever version is current at execution time, creating a supply-chain risk and making behavior non-reproducible. If the upstream package is compromised or changed incompatibly, users may execute malicious or unsafe code during install.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

Using npx clawhub@latest pulls whatever version is current at execution time, creating a supply-chain risk and making behavior non-reproducible. If the upstream package is compromised or changed incompatibly, users may execute malicious or unsafe code during install.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

Using npx clawhub@latest pulls whatever version is current at execution time, creating a supply-chain risk and making behavior non-reproducible. If the upstream package is compromised or changed incompatibly, users may execute malicious or unsafe code during install.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

Using npx clawhub@latest pulls whatever version is current at execution time, creating a supply-chain risk and making behavior non-reproducible. If the upstream package is compromised or changed incompatibly, users may execute malicious or unsafe code during install.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

Using npx clawhub@latest pulls whatever version is current at execution time, creating a supply-chain risk and making behavior non-reproducible. If the upstream package is compromised or changed incompatibly, users may execute malicious or unsafe code during install.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

Using npx clawhub@latest pulls whatever version is current at execution time, creating a supply-chain risk and making behavior non-reproducible. If the upstream package is compromised or changed incompatibly, users may execute malicious or unsafe code during install.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill states that scripts in the package make no network calls, yet nearby instructions direct users to clone repositories, install remote requirements, use Hugging Face resources, and publish through ClawHub. This inconsistency can cause users to underestimate network exposure and supply-chain risk when following the documented workflow.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

Using 'npx clawhub@latest install ...' executes an unpinned package version at runtime, which makes the install behavior dependent on whatever version is currently published. If the upstream package is compromised or a breaking/malicious release is published, users following this documentation could execute attacker-controlled code.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

This command relies on 'npx clawhub@latest', which fetches and runs the newest published version instead of a reviewed, fixed version. That creates a supply-chain risk where a compromised or unexpected update could run arbitrary code on the user's machine during installation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The install instruction invokes an unpinned package manager helper via NPX, so trust is delegated to the current registry state at execution time. In a skill ecosystem that encourages installing additional companion skills, this increases exposure to supply-chain compromise or unexpected behavior changes.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

Because the command uses '@latest', a user cannot reproduce the exact reviewed installation path later, and a future malicious publish could be executed simply by copying the documented command. This is a classic documentation-induced supply-chain weakness rather than a direct code flaw in the markdown itself.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The final companion-skill install example still depends on executing the latest clawhub package from the registry, which is unsafe for security-sensitive setup instructions. If exploited, an attacker controlling or compromising that package release path could achieve arbitrary code execution on systems following the docs.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

Using 'npx clawhub@latest publish ...' executes the latest package version at runtime without pinning, which creates a supply-chain risk: a compromised or malicious newly published version could run arbitrary code in the maintainer's environment. This is more dangerous here because the file is an operator reference with explicit maintainer commands, increasing the chance that someone will copy-paste and execute it during release workflows.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/stack_healthcheck.py (reported line 48)May include surrounding context.

python
if not cmd[1] or not Path(cmd[1]).is_file():
            print(f"  SKIP {name} (script missing)")
            continue
        r = subprocess.run(cmd, cwd=root, capture_output=True, text=True, timeout=120)
        status = "OK" if r.returncode == 0 else f"FAIL({r.returncode})"
        print(f"  {name}: {status}")
        if r.returncode == 0:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/stack_healthcheck.py (reported line 55)May include surrounding context.

python
ok += 1
    gate = SKILL_ROOT / "scripts" / "lygo_p0_gate.py"
    if gate.is_file():
        r = subprocess.run([sys.executable, str(gate), str(SKILL_ROOT / "SKILL.md")], capture_output=True)
        print(f"  P0 gate SKILL.md: {'OK' if r.returncode == 0 else 'SOFTEN/QUARANTINE'}")
    print(f"Done ({ok} stack checks). HF dataset: https://huggingface.co/datasets/DeepSeekOracle/lygo-protocol-stack")
    return 0 if ok else 1

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The manifest description at L003 includes the absolute claim 'No secrets.' Later, L183 clarifies that tokens may be loaded from the user environment at runtime, meaning the skill's documented operation does involve secret material even if it does not store or commit it. That is a documentation-level contradiction about whether secrets are involved at all.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The file documents python tools/hf_push_dataset.py, which implies a network upload to Hugging Face, but the surrounding text does not warn about transmitting local data or verifying dataset contents before upload. Although marked 'maintainers only,' it still omits a clear disclosure about privacy and publication impact in this markdown description.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.