Back to skill

Security audit

data-rights-guard

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent and not malicious, but its rights-checking logic can incorrectly approve restricted data and its install instructions rely on mutable remote tooling.

Install only from a pinned, reviewed version or commit. Treat this as an advisory helper, not an automated compliance gate: manually review non-commercial, unknown, missing, and attribution-bearing licenses, and do not rely on its process exit code in CI until 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/rights_guard.py:6
Finding
Rights validation fails open and can approve restricted training data## Vulnerability Details **File Location**: `scripts/rights_guard.py`, lines 6-21 **Vulnerability Type**: Fail-open authorization and license validation **Risk Level**: High ### Vulnerable Code ```python def rate(entry): lic = (entry.get("license") or "").strip().lower() commercial = entry.get("commercial", True) attr = entry.get("attribution", False) source = (entry.get("source") or "").strip() problems = [] if not lic: problems.append("无许可证(高危)") if commercial is False or "non-commercial" in lic or "nc" == lic: problems.append("非商用锁(不可商用)") if attr is True and not entry.get("attributed", False): problems.append("需署名但未标") if not source: problems.append("来源不可溯(隔离待核)") if any("高危" in p or "非商用" in p for p in problems): return "排除", problems if problems: return "需处理", problems return "可训练", problems ``` ### Technical Analysis The commercial-use field defaults to `True` when it is absent. Consequently, an entry with no affirmative evidence of commercial authorization is treated as commercially permitted. The lexical license check only rejects licenses containing the exact substring `non-commercial` or whose complete normalized value is `nc`. Common non-commercial identifiers such as `CC-BY-NC-4.0` do not satisfy either condition. Unknown but nonempty license strings are also accepted without review. Attribution restrictions are trusted from the caller-supplied `attribution` Boolean rather than being inferred from recognized license terms. A manifest producer can therefore omit that field even when the declared license requires attribution. These conditions collectively create a fail-open gate: unsupported, ambiguous, or incompletely described licensing information can receive the final trainable status. ### Attack Path 1. A dataset supplier creates an entry with `license` set to `CC-BY-NC-4.0`. 2. ...[truncated 817 chars]
Remediation
## Remediation Suggestions - Default missing commercial authorization to unknown or denied rather than `True`. - Maintain an explicit, normalized mapping of recognized license identifiers and their commercial-use, attribution, redistribution, and derivative-work requirements. - Recognize standard identifiers such as SPDX expressions and Creative Commons variants. - Route unknown, malformed, custom, or ambiguous licenses to manual review. - Infer restrictions from the recognized license instead of relying solely on caller-supplied Boolean fields. - Require affirmative evidence of commercial rights before assigning a trainable status. - Add regression tests for `CC-BY-NC-4.0`, `CC-BY-4.0`, custom licenses, missing fields, mixed-case identifiers, and whitespace variations.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/rights_guard.py:23
Finding
Invalid and rejected scans can return a successful process status## Vulnerability Details **File Location**: `scripts/rights_guard.py`, lines 23-49 **Vulnerability Type**: Fail-open input validation and incorrect exit-status handling **Risk Level**: High ### Vulnerable Code ```python def main(): ap = argparse.ArgumentParser() ap.add_argument("--manifest", required=True) ap.add_argument("--json", action="store_true") a = ap.parse_args() items = json.loads(pathlib.Path(a.manifest).read_text(encoding="utf-8")) if isinstance(items, dict): items = items.get("items", []) out = [] excl = 0 for e in items: st, probs = rate(e) if st == "排除": excl += 1 out.append({"id": e.get("id", "?"), "status": st, "problems": probs}) if a.json: print(json.dumps({"items": out, "excluded": excl, "advice": "排除项不出训练集;需处理项补全后再进"}, ensure_ascii=False, indent=2)) else: for o in out: icon = "✅" if o["status"] == "可训练" else "⚠️" if o["status"] == "需处理" else "🔒" print(f" {icon} [{o['status']}] {o['id']} {o['problems'] or ''}") print(f"\n排除出训练集:{excl} 建议:排除项不出集,需处理项补全后再进") if __name__ == "__main__": main() ``` The documented contract in `SKILL.md`, lines 69-70, states that exit status 0 means success, status 1 means issues were found, and status 2 means a usage or environment error. The implementation does not implement that contract. ### Technical Analysis The program never returns a status from `main()` or calls `sys.exit()` with a result derived from the scan. Python therefore exits with status 0 after normal execution even when one or more entries are excluded or require remediation. A top-level JSON object without an `items` property is silently converted to an empty list through `items.get("items", [])`. This makes a malformed or unrelated manifest appear to be a successful scan of zero entries. The bundled project-level `manifest.json` h ...[truncated 1408 chars]
Remediation
## Remediation Suggestions - Validate the top-level JSON schema before processing. - Require `items` to exist and be a list when object-form input is used. - Reject an empty list unless the user explicitly authorizes an empty scan. - Validate that every item is an object and that all fields have expected types. - Return exit status 1 whenever any entry is excluded or remains unresolved. - Return exit status 2 for malformed JSON, invalid schema, unreadable files, or invalid arguments. - Invoke the program through `raise SystemExit(main())` and have `main()` return the documented status. - Catch expected parsing and file errors and emit concise diagnostic messages instead of raw stack traces. - Add automated tests that assert both output content and process status for successful, excluded, unresolved, empty, and malformed inputs.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:85
Finding
Installation instructions execute unpinned third-party tooling and install mutable repository content## Vulnerability Details **File Location**: `SKILL.md`, lines 85-91 **Vulnerability Type**: Unpinned third-party installation and supply-chain exposure **Risk Level**: Medium ### Vulnerable Code ```bash npx skills add zhaoxinghua09-cell/agent-skills -g git clone https://github.com/zhaoxinghua09-cell/agent-skills.git cp -r agent-skills/skills/data-rights-guard ~/.workbuddy/skills/ ``` ### Technical Analysis The `npx skills` command does not specify an immutable package version or integrity value. Depending on local package availability and npm behavior, `npx` may retrieve and execute the current published version of a third-party command-line package. The effective installer code can therefore change after this skill has been audited. The installation source is also the mutable head of a remote Git repository rather than a pinned commit or signed release artifact. The global installation flag and copy into an Agent skill directory expand the consequences of a compromised package, account, or repository. The bundled `rights_guard.py` itself does not retrieve or execute remote code. The risk arises specifically from the documented installation workflow. ### Attack Path 1. An attacker compromises the npm package used by `npx`, its publisher account, the referenced GitHub account, or the repository's default branch. 2. The attacker publishes or commits modified installation logic or skill files. 3. A user follows the documented command without pinning or integrity verification. 4. In the `npx` path, the mutable package code executes with the invoking user's privileges. 5. In the repository path, compromised skill content is copied into the user's Agent skill directory. 6. The malicious content can affect subsequent Agent runs or access resources available to the user when invoked. ### Impact Assessment Successful exploitation of the `npx` path can execute code with the privileges of the user running the command. ...[truncated 574 chars]
Remediation
## Remediation Suggestions - Pin the `skills` CLI to a reviewed, exact package version. - Pin the Git source to a specific audited commit hash or signed release tag. - Publish and verify cryptographic checksums or signatures for release artifacts. - Avoid global installation by default and use the least-privileged installation scope. - Install only the reviewed skill directory rather than relying on mutable content from a larger repository. - Document the expected package publisher, repository commit, checksum, and verification procedure. - Prefer downloading a versioned release archive and verifying its integrity before copying any files. - Re-audit the resolved installer and skill contents whenever the pinned version is changed.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Rp1

Medium
Category
MCP Rug Pull
Confidence
84% confidence
Finding
The installation instruction uses `npx skills` without pinning a specific package version, which can cause users to fetch and execute whatever version is current at install time. If the upstream package is compromised, typosquatted, or changed in a malicious way, this becomes a supply-chain execution risk because `npx` may run unreviewed remote code during installation.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The module docstring and all user-facing status/output strings are in Chinese, which indicates the skill is designed to communicate in a single language. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly documented and justified, which is not present here.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
This markdown file contains user-facing natural language primarily in Chinese, including the core attestation content, and does not indicate that another language is available or that Chinese is optional. Under the policy rule for language/locale constraints, forcing a specific language without user opt-in can be a policy concern.

Natural-Language Policy Violations

Low
Confidence
83% confidence
Finding
The manifest sets the category to "AI合规", which imposes a specific language/locale in user-visible metadata. There is no indication in this file that the language choice is optional, user-selected, or justified as a region-specific constraint.

Static analysis

No suspicious patterns detected.