Back to skill

Security audit

skill-quality-gate

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real skill-quality checker, but its installer and gate implementation can give users false confidence and should be reviewed before use.

Install only from a pinned, reviewed commit or signed release, avoid the unpinned global npx path, and do not rely on this script as an automated publish blocker until its exit codes and secret scanning are fixed. Treat its results as a lightweight checklist requiring human review, not a security guarantee.

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/quality_gate.py:68
Finding
Failed Quality Gates Return a Successful Process Exit Status<![CDATA[ ## Vulnerability Details **File Location**: `scripts/quality_gate.py`, lines 68-77 **Vulnerability Type**: Release-gate fail-open behavior **Risk Level**: High ### Vulnerable Code ```python print(f"质量门禁:{base}\n" + "=" * 40) passed = 0 for name, ok, fix in results: print(f" [{'PASS' if ok else 'FAIL'}] {name}" + (f" → {fix}" if fix and not ok else "")) passed += ok print("=" * 40) print(f"结果:{passed}/{len(results)} → {'✅ 放行' if passed == len(results) else '🔒 拦截发布'}") if __name__ == "__main__": main() ``` ### Technical Analysis The validator visually reports failed checks but does not return or raise a nonzero process status. Because `main()` completes normally, the Python interpreter exits with status `0`, regardless of whether any quality check failed. This contradicts the documented behavior in `SKILL.md`, which states that the program returns `0` on success, `1` when issues are detected, and `2` for usage or environmental errors. Automated release systems normally rely on process exit status rather than parsing human-readable output. Consequently, this implementation is fail-open when integrated into CI/CD or marketplace publication workflows. ### Attack Path 1. An attacker or contributor prepares a Skill containing prohibited or noncompliant content. 2. The release pipeline invokes: ```bash python scripts/quality_gate.py --dir ./submitted-skill ``` 3. One or more checks print `FAIL`, and the summary claims that publication is blocked. 4. The script reaches the end of `main()` without raising `SystemExit` or returning a status to the interpreter. 5. The operating system records exit status `0`. 6. The release pipeline interprets the validator as successful and continues publishing the submitted Skill. ### Impact Assessment This issue can bypass every quality rule implemented by the validator, including the plaintext-secret check. It does not directly grant operating-system privileges, ...[truncated 253 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Return an explicit status from `main()` and propagate it to the operating system: ```python def main(): # Existing validation logic return 0 if passed == len(results) else 1 if __name__ == "__main__": raise SystemExit(main()) ``` Handle argument, filesystem, decoding, and environmental errors separately with exit status `2`. Add automated tests asserting that: - All checks passing produces exit status `0`. - Any individual check failing produces exit status `1`. - Missing or invalid arguments produce exit status `2`. - CI publication is halted on every nonzero status. Release automation should also treat an absent, terminated, or malformed validator result as failure rather than success. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/quality_gate.py:43
Finding
Secret Scanner Allows Common Credential Formats to Pass the Release Gate<![CDATA[ ## Vulnerability Details **File Location**: `scripts/quality_gate.py`, lines 43-47 **Vulnerability Type**: Incomplete sensitive-data detection **Risk Level**: High ### Vulnerable Code ```python # 5 无密钥 secret = re.compile(r"(ghp_[A-Za-z0-9]{8,}|sk-[A-Za-z0-9]{8,}|password\s*=\s*\S+)", re.I) has_secret = any(secret.search(f.read_text(encoding="utf-8", errors="ignore")) for f in base.rglob("*") if f.is_file() and f.suffix in (".md", ".py", ".json", ".txt", ".yml", ".yaml")) check("无密钥明文", not has_secret) ``` ### Technical Analysis The scanner only detects three narrow patterns: - Strings beginning with `ghp_` - Strings beginning with `sk-` - Unquoted values matching `password=<non-whitespace>` It does not cover many commonly published secrets, including AWS access keys, GitLab or Slack tokens, bearer tokens, private-key blocks, database connection strings, quoted password assignments, client secrets, certificates, credentials in unsupported file extensions, or high-entropy values. The use of `errors="ignore"` can also silently remove undecodable bytes, potentially preventing detection in malformed text files. The resulting pass status is presented as confirmation that no plaintext key exists even though the implementation is only a limited heuristic. ### Attack Path 1. A contributor places a credential in a scanned package using an unsupported format, such as a private-key block, bearer token, quoted password, or cloud-provider access key. 2. The release process invokes the quality gate. 3. The credential does not match any of the three regular-expression alternatives. 4. `has_secret` remains false, so the plaintext-secret dimension passes. 5. If the publication workflow accepts the result, the credential is distributed with the Skill. 6. A recipient or automated crawler extracts and uses the exposed credential against its associated service. ### Impact Assessment The exact privileges depend on the leaked ...[truncated 335 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Replace the narrow expression with a layered detection strategy: 1. Integrate a maintained secret-scanning engine or ruleset covering major cloud providers, source-control services, messaging platforms, private keys, bearer tokens, connection strings, and generic credential assignments. 2. Detect quoted and unquoted values in JSON, YAML, environment files, shell scripts, configuration files, and source code. 3. Scan PEM and other private-key headers. 4. Add entropy-based detection for unknown token formats, with reviewed allowlists to control false positives. 5. Avoid silently ignoring decoding failures; report skipped or undecodable files as gate failures requiring review. 6. Document that scanning is heuristic and does not prove the absence of secrets. 7. Add test fixtures for representative supported and unsupported credential formats. 8. Combine automated scanning with repository history scanning and human review before publication. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:80
Finding
Installation Instructions Use Unpinned Third-Party Code Sources<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 80-86 **Vulnerability Type**: Mutable and unverified supply-chain dependency **Risk Level**: Medium ### Vulnerable Code ```bash # One-command installation using the Skills CLI npx skills add zhaoxinghua09-cell/agent-skills -g # Manual installation git clone https://github.com/zhaoxinghua09-cell/agent-skills.git cp -r agent-skills/skills/skill-quality-gate ~/.workbuddy/skills/ ``` ### Technical Analysis The `npx` command does not pin the `skills` package to a reviewed version or integrity digest. Depending on the local package-manager state, `npx` may retrieve and execute package content from a remote registry. The global installation option also increases the persistence and scope of any compromised package behavior. The alternative Git command clones the repository's mutable default branch rather than a reviewed tag or commit. Therefore, the installed content may differ from the artifact covered by this audit. Neither installation path provides a checksum, signature, or immutable reference that lets users verify provenance and integrity. ### Attack Path 1. An attacker compromises the package-registry account, the source repository, a maintainer account, or the relevant upstream release process. 2. The attacker publishes malicious package content or modifies the repository's default branch. 3. A user follows the documented `npx` or `git clone` installation procedure. 4. The mutable remote content is retrieved instead of the reviewed artifact. 5. In the `npx` path, package code may execute during installation; in either path, altered Skill content is installed. 6. The malicious content receives the permissions of the invoking user and can affect subsequent Agent sessions if installed into a global or persistent Skill directory. ### Impact Assessment No malicious upstream content was observed in the audited artifact, so exploitation requires a supply-chain compromise. If compromise ...[truncated 295 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin the CLI package to a reviewed version rather than invoking an unversioned package. - Pin repository installation to a specific audited commit or signed release tag. - Publish cryptographic checksums or signed provenance attestations for release artifacts. - Verify signatures and checksums before copying files into an Agent Skill directory. - Avoid global installation unless it is necessary. - Prefer downloading and inspecting an immutable artifact before executing installation tooling. - Document the exact commit corresponding to each Skill version. - Add a controlled update process that requires renewed review when upstream content changes. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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
Findings (6)

Lp3

Medium
Category
MCP Least Privilege
Confidence
77% confidence
Finding
The skill describes code-adjacent behavior and installation/CLI usage that implies filesystem access, but it does not declare any explicit tool scope such as allowed tools or permissions. In agent environments, undeclared capabilities can cause over-broad runtime access or make reviewers assume the skill is non-operative documentation when it actually drives file reads during quality checks.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The trigger phrases are broad enough to match ordinary discussion about publishing or checking quality, which can cause unintended activation of the skill. In an agentic workflow, that can redirect user intent, trigger unnecessary file inspection, or cause the model to apply gatekeeping logic when the user only wanted casual advice.

Vague Triggers

Medium
Confidence
84% confidence
Finding
The '主动推荐' section encourages unsolicited invocation based on generic publishing-related signals rather than explicit user consent. This increases the chance the agent will intervene outside the user's intended task, potentially inspecting artifacts or blocking flow in ways that are surprising and difficult to audit.

Rp1

Medium
Category
MCP Rug Pull
Confidence
86% confidence
Finding
The installation instruction uses an unpinned NPX package reference, which allows whatever version is currently published to be fetched and executed at install time. If the upstream package is compromised or changes behavior, users may run attacker-controlled code or receive a different tool than the reviewed skill expected.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The module docstring is entirely in Chinese and presents the skill as a general-purpose quality gate, with no indication that Chinese output is optional or that the tool is limited to a Chinese-specific context. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
This file begins with a bilingual heading and the substantive content is primarily in Chinese, but it does not indicate that language selection is optional or user-configurable. The policy calls for flagging language or locale constraints when they are imposed without user opt-in or justification.

Static analysis

No suspicious patterns detected.