Back to skill

Security audit

LYGO Geodesic Sealer (P6 Quantum-Attest)

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly local and consent-gated, but its verifier can accept incomplete forged artifacts and its install command runs a mutable installer.

Review before installing. Pin or independently verify the installer, keep --network off unless needed, use only a trusted LYGO_STACK_ROOT, do not put secrets in truth/chaos payloads, and do not treat this verifier as strong cryptographic proof until its fail-open checks are fixed.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/seal_cli.py:465
Finding

Artifact Verification Fails Open When Integrity Evidence Is Missing

Content
View full analysis
dict[str, Any]: """Recompute provenance / merkle consistency for a seal or lock artifact.""" checks: dict[str, Any] = {"ok": False, "signature_match": obj.get("signature") == SIG} kind = obj.get("kind") or "" if kind == "psi_sign" or "provenance" in obj: prov = obj.get("provenance") or (obj.get("psi") or {}).get("provenance") if not prov and "provenance" in obj: prov = obj["provenance"] if prov: recomputed = sha256_bytes(canonical_json(prov)) checks["provenance_match"] = recomputed == obj.get("provenance_sha256") else: checks["provenance_match"] = None if kind in ("geodesic_lock", "p6_quantum_attest") or obj.get("merkle_root") or ( isinstance(obj.get("lock"), dict) and obj["lock"].get("merkle_root") ): lock = obj if kind == "geodesic_lock" else obj.get("lock") or obj leaves = lock.get("leaves_sha256") or [] if leaves: recomputed_root = merkle_root(leaves) checks["merkle_match"] = recomputed_root == lock.get("merkle_root") else: checks["merkle_match"] = None psi = lock.get("psi") or (obj.get("psi") or {}).get("psi") or obj.get("psi") if isinstance(psi, dict) and "prob_truth" in psi: checks["no_collapse"] = psi.get("prob_truth", 0) > 1e-9 and psi.get("prob_chaos", 0) > 1e-9 else: checks["no_collapse"] = True if kind == "p6_quantum_attest": checks["has_badge"] = bool(obj.get("badge")) checks["attestation_present"] = bool(obj.get("attestation")) # overall required = [checks.get("signature_match")] if "provenance_match" in checks and checks["provenance_match"] is not None: ...[truncated 2310 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/seal_cli.py:141
Finding

Network Allowlist Can Be Bypassed Through Redirects and Responses Are Read Without a Size Limit

Content
View full analysis
dict[str, Any]: if not https_only(url): return {"ok": False, "status": 0, "error": "https_only", "bytes": 0, "sha256": None} req = urllib.request.Request(url, headers={"User-Agent": UA}, method="GET") try: with urllib.request.urlopen(req, timeout=timeout) as resp: body = resp.read() sample = body[: 2_000_000] return { "ok": 200 <= resp.status < 400, "status": resp.status, "error": None, "bytes": len(body), "sha256": sha256_bytes(sample) if sample else None, "body_sample": sample if url.endswith(".json") and len(body) < 5_000_000 else None, } ``` ### Technical Analysis The initial URL is checked for an HTTPS scheme, and callers currently provide fixed endpoint URLs. However, `urllib.request.urlopen` follows redirects automatically. The code does not validate each redirect target or the final response URL against the declared hostname allowlist. Therefore, a compromised or modified allowlisted endpoint can redirect the request to an undeclared external, internal, or non-HTTPS destination. This conflicts with the documented guarantee that network access is restricted to fixed HTTPS dual-ledger endpoints. The response-size handling also applies the two-megabyte slice only after `resp.read()` has loaded the entire response into memory. A remote server can return an arbitrarily large or endless response, subject only to environmental limits and timeout behavior, causing excessive memory use or process termination. The request uses only a static User-Agent and does not transmit truth/chaos payloads, local files, cr ...[truncated 1436 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:64
Finding

Installation Instructions Execute a Mutable Unpinned Package Release

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding

Using npx clawhub@latest install ... pulls and executes the latest published version of the installer at runtime, which creates a supply-chain risk if that package is compromised or a breaking/malicious version is released. In a skill-install context this is more dangerous because users are encouraged to run the command directly, effectively granting code execution before the skill is reviewed locally.

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.

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.

Scope Creep

Low
Category
Excessive Agency
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.

Content

Scanner excerpt · LICENSE (reported line 12)May include surrounding context.

text
permit persons to whom the Software is furnished to do so.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE

Static analysis

No suspicious patterns detected.