Back to skill

Security audit

evidence-chain-check

Security checks for vulnerabilities and agentic risk

Overview

This skill is a small evidence-chain checker with no apparent exfiltration or persistence, but its legal/compliance integrity claims are stronger than the checks it actually performs and its install instructions use mutable unpinned sources.

Review before installing. Use this only as a lightweight structural checker, not as proof of legal evidence integrity or cryptographic tamper resistance. Prefer installing from a pinned reviewed commit or release, avoid global installation unless needed, and require human/legal review for any real evidence or compliance decision.

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)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:75
Finding
Unpinned Third-Party Code Execution in the Recommended Installation Command<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:75-77` **Vulnerability Type**: Unpinned package and repository supply chain **Risk Level**: Medium ### Vulnerable Code ```bash # One-click retrieval (skills CLI) npx skills add zhaoxinghua09-cell/agent-skills -g ``` ### Technical Analysis The recommended installation procedure invokes the `skills` npm package through `npx` without specifying an exact package version. Depending on the local npm configuration and cache state, `npx` can download and execute the current version of that package from a remote registry. The referenced repository is also identified by a mutable repository name rather than an immutable commit hash or signed release. Consequently, the code executed or installed at deployment time can differ from the artifact reviewed during this audit. The global installation flag (`-g`) increases the scope of any compromised installation by placing content in globally accessible locations for the invoking user. No evidence shows that the current package or repository is malicious. The vulnerability arises from trusting mutable, unverified upstream content during installation. ### Attack Path 1. An attacker compromises the npm package, its publisher account, the package registry path, or the referenced source repository. 2. The attacker publishes a modified package version or replaces repository content. 3. A user follows the documented installation command. 4. `npx` retrieves and executes the current unpinned package. 5. The compromised installer runs with the privileges of the invoking user and can install altered Skill content globally. ### Impact Assessment Successful exploitation could execute arbitrary code with the privileges of the user running `npx`. The attacker could read or modify files accessible to that user, steal environment variables or credentials, alter installed Skills, and introduce malicious instructions or scripts into the global Skill installation. The co ...[truncated 208 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the CLI to an exact reviewed version, for example by using an explicit npm version rather than the latest available release. 2. Pin the Skill repository to an immutable commit hash or cryptographically signed release. 3. Publish and verify SHA-256 checksums or signed provenance attestations before installation. 4. Avoid global installation unless it is operationally required. Prefer a project-local or isolated installation. 5. Disable or carefully review package lifecycle scripts where supported. 6. Document the expected package publisher, registry, version, repository commit, and verification procedure. 7. Periodically review pinned dependencies and update them through a controlled security-review process. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/evidence_chain_check.py:18
Finding
Hash-Chain Integrity Can Be Forged Without Cryptographic Verification<![CDATA[ ## Vulnerability Details **File Location**: `scripts/evidence_chain_check.py:18-22` **Vulnerability Type**: Incomplete cryptographic integrity validation **Risk Level**: High ### Vulnerable Code ```python h = e.get("hash") if prev_hash is not None and e.get("prev") != prev_hash: breaks.append("哈希链断裂 @" + str(i)) prev_hash = h ``` ### Technical Analysis The implementation compares each record's attacker-controlled `prev` field with the preceding record's attacker-controlled `hash` field. It does not independently compute a cryptographic digest from the evidence record, validate a hash algorithm or encoding, require hashes to be present, or authenticate the final chain state against a trusted external anchor. As a result, the check establishes only internal string equality. It does not prove that record contents correspond to their declared hashes or that the chain has not been rewritten. The treatment of missing hashes further weakens validation. If `prev_hash` is `None`, the comparison is skipped. A chain in which hashes are omitted can therefore bypass meaningful linkage checks and may still be returned as complete when the timestamp and subject checks pass. This is particularly significant because the Skill represents itself as an evidence-chain integrity checker. Consumers may treat exit code 0 or `"complete": true` as evidence of cryptographic integrity even though no cryptographic verification occurred. ### Attack Path 1. An attacker obtains or constructs an evidence-chain JSON document. 2. The attacker changes one or more evidence records. 3. The attacker assigns arbitrary matching values to adjacent `hash` and `prev` fields, or omits hash fields so that comparisons are skipped. 4. The attacker submits the modified JSON through the `--chain` argument. 5. The checker observes matching declared strings and finds no hash-chain break. 6. If subject and timestamp checks also pass, the tool returns `"compl ...[truncated 813 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Define a canonical serialization for every hash-covered record. Exclude only the fields explicitly defined by the chain protocol, such as the record's own digest. 2. Select and document an approved cryptographic algorithm, such as SHA-256 or SHA-512. 3. Recompute every record's hash from its canonicalized contents and reject any mismatch. 4. Require `hash` and `prev` fields for all applicable records and validate their exact encoding and digest length. 5. Define and validate genesis-record behavior explicitly rather than skipping validation based only on a `None` value. 6. Bind each record to the previous record's verified digest. 7. Authenticate the terminal digest using a trusted digital signature, timestamp authority, append-only log, or independently stored anchor. Otherwise, an attacker able to rewrite the whole chain can recompute every hash. 8. Reject unknown, missing, null, or incorrectly typed security-critical fields. 9. Add negative tests covering modified contents, fabricated matching strings, omitted hashes, reordered records, duplicate records, and fully recomputed but unauthenticated chains. 10. Clarify in documentation whether the tool performs structural linkage checks or genuine cryptographic integrity verification. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/evidence_chain_check.py:30
Finding
Structurally Invalid JSON Can Trigger Unhandled Exceptions and Tracebacks<![CDATA[ ## Vulnerability Details **File Location**: `scripts/evidence_chain_check.py:30-33` **Vulnerability Type**: Missing input schema validation and exception handling **Risk Level**: Medium ### Vulnerable Code ```python if not a.chain: print("用法: --chain <JSON>", file=sys.stderr); sys.exit(2) try: chain = json.loads(a.chain) except Exception as e: print("chain JSON 解析失败: " + str(e), file=sys.stderr); sys.exit(2) r = check(chain) ``` The unchecked call reaches the following assumptions in `check()`: ```python for i, e in enumerate(chain): subj = e.get("subject") if subj: subjects.add(subj) t = e.get("time") if last_t is not None and t is not None and t < last_t: breaks.append("时间倒序 @" + str(i)) ``` ### Technical Analysis The program catches JSON syntax errors from `json.loads()`, but it does not validate the resulting data structure before passing it to `check()`. Syntactically valid JSON is not necessarily valid evidence-chain input. The implementation assumes that: - The root value is an iterable array. - Every array element is an object with a `.get()` method. - Every non-null timestamp can be compared with the preceding timestamp. - Every subject is hashable and all subjects are mutually sortable. These assumptions can be violated by valid JSON. For example: - A root object causes iteration over string keys, after which `e.get()` fails. - An array containing a number or string causes `AttributeError`. - Mixed timestamp types such as a number followed by a string cause `TypeError`. - An object or array used as a subject is unhashable and causes `TypeError`. - Mixed subject scalar types can fail during `sorted(subjects)`. Because only parsing is protected by `try`/`except`, these exceptions escape from `check()`. Python then emits a traceback and terminates outside the documented controlled exit behavior. ### Attack Path 1. An attacker supplies syntactically valid but structura ...[truncated 988 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate the decoded JSON against a strict schema before calling `check()`. 2. Require the root value to be an array and every element to be an object. 3. Define mandatory fields and accepted types for `id`, `time`, `subject`, `hash`, and `prev`. 4. Reject null values, booleans, arrays, and objects where scalar values are required. 5. Normalize timestamps to one documented representation, preferably an integer epoch value or strictly parsed RFC 3339 timestamp, before comparison. 6. Require subjects to be non-empty strings to ensure they are hashable and sortable. 7. Return a concise validation error and exit code 2 for malformed structures. 8. Catch expected validation exceptions around both decoding and checking while avoiding broad suppression of programming errors. 9. Ensure production CLI failures do not emit raw tracebacks or local paths. 10. Add tests for non-array roots, scalar entries, missing fields, null values, mixed timestamp types, unhashable subjects, empty chains, and excessively nested or large inputs. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (5)

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The skill title, usage guidance, FAQ, theory, and disclaimer are written in Chinese, and the operational instruction in the matrix tells agents to follow this SKILL.md workflow. Although there is an English display name in metadata, the actual user-facing instructions do not offer a language/locale choice, which can violate language-policy requirements for multilingual environments.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding
The skill instructs users to run `npx skills add ...` without pinning a specific package version or integrity. That can cause execution of an unexpected or newly published package version at install time, creating a supply-chain risk if the package is updated maliciously or compromised.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
This code includes natural-language strings in Chinese in the module docstring, CLI help text, error messages, and normal output. Under the policy, forcing a specific language without user opt-in can be a language/locale policy violation, and the file does not offer alternative locales or explain that the tool is intentionally region-specific.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The file presents the skill description, usage context, and operational guidance only in Chinese. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale restriction is documented and justified.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The manifest contains the category value "AI 治理", which fixes part of the skill metadata in Chinese without any indication that the skill is region-specific or that users can choose locale. Under the policy rule, forcing a specific language without opt-in can be a natural-language policy concern.

Static analysis

No suspicious patterns detected.