Back to skill

Security audit

元测 yotta-security-testing

Security checks for vulnerabilities and agentic risk

Overview

This is mostly a disclosed authorized security-testing helper, but it needs Review because it can persist sensitive targets in local logs/reports and its installer has broad user-level agent installation behavior.

Install only if you are comfortable with a local security-testing skill that writes persistent scope and audit files. Avoid putting passwords, tokens, cookies, or authenticated URLs in targets or scan metadata, prefer a pinned package version over the unpinned npx command, and avoid broad multi-agent installation unless you intentionally want the skill in those agent environments.

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
README.md:136
Finding
Unpinned npm Package Is Downloaded and Executed During Recommended Installation## Vulnerability Details **File Location**: `README.md:136-138` **Vulnerability Type**: Supply-chain exposure through mutable package execution **Risk Level**: Medium ### Vulnerable Code ```text # Optional China mirror: npm config set registry https://registry.npmmirror.com npx -y @yottameta/yotta-security-testing --agent <agent-name> # install to the agent's default user-level skills dir npx -y @yottameta/yotta-security-testing --dir <your-skills-dir> # point to the skills dir itself (e.g. ~/.codex/skills) ``` Equivalent unpinned commands also appear in `README.zh-CN.md:128-130`. ### Technical Analysis The recommended installation procedure invokes `npx -y` without specifying an exact package version or verifying package integrity. The effective executable is therefore the package version resolved by the configured npm registry at installation time, rather than the version reviewed in this audit. The `-y` option suppresses the normal confirmation prompt. The package exposes `bin/install.js` as its executable, so the downloaded package immediately receives the current user's filesystem privileges. Its intended behavior includes writing into user-level Agent skill directories. The optional `npm config set registry` command changes the user's persistent npm registry configuration. This broadens the trust decision beyond this installation because subsequent npm commands may also resolve packages through that mirror. No malicious dependency or remote payload was found in the audited artifact. The issue is that the documented process does not cryptographically bind installation to this reviewed version. ### Attack Path 1. An attacker compromises the npm publisher account, configured registry, mirror, or package release process. 2. The attacker publishes or serves a modified version under `@yottameta/yotta-security-testing`. 3. A user follows the recommended unpinned `npx -y` command. 4. npm resolves ...[truncated 803 chars]
Remediation
## Remediation Suggestions 1. Pin installation commands to an audited exact version, for example: ```text npx @yottameta/yotta-security-testing@0.3.0 --agent <agent-name> ``` 2. Avoid `-y` so users retain an explicit execution confirmation. 3. Publish package integrity information and document verification of the npm tarball before execution. 4. Prefer downloading and inspecting a pinned package archive before running its installer. 5. Use a command-scoped registry option instead of persistently changing the user's npm registry configuration. 6. Protect publisher accounts with phishing-resistant multi-factor authentication and restricted release tokens. 7. Add reproducible release and provenance controls so users can compare the registry artifact with the reviewed repository revision.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/yotta_security_testing.py:529
Finding
Credentials in Target URLs Are Persisted in Plaintext Audit Logs## Vulnerability Details **File Location**: `scripts/yotta_security_testing.py:529-566` and `scripts/yotta_security_testing.py:776-777` **Vulnerability Type**: Plaintext sensitive-data logging **Risk Level**: Medium ### Vulnerable Code ```python if host in ABSOLUTE_DENY_HOSTS: audit(cfg_dir, "scope.check", target=raw, host=host, result="deny", reason="absolute-deny") result = {"result": "deny", "reason": "absolute-deny", "exit": EXIT_DENY_FORBIDDEN, "message": "拒绝:%s 为云元数据 / 管理面目标,禁止测试(exit %d)" % (host, EXIT_DENY_FORBIDDEN)} else: target_type, high = classify_target(host) idx, entry = find_match(scope, host, port, path, raw) if entry is not None and is_expired(entry): audit(cfg_dir, "scope.check", target=raw, host=host, result="deny", reason="expired", entry_index=idx + 1) result = {"result": "deny", "reason": "expired", "exit": EXIT_DENY_UNAUTHORIZED, "entry_index": idx + 1, "message": "拒绝:命中授权条目 #%d 但已过期(expires=%s)" % (idx + 1, entry.get("expires"))} elif entry is not None and high and entry.get("type") != "explicit": audit(cfg_dir, "scope.check", target=raw, host=host, result="deny", reason="high-sensitivity-needs-explicit", entry_index=idx + 1, entry_type=entry.get("type")) elif entry is not None: audit(cfg_dir, "scope.check", target=raw, host=host, result="allow", reason="whitelist", entry_index=idx + 1, entry_type=entry.get("type")) else: audit(cfg_dir, "scope.check", target=raw, host=host, result="deny", reason="not-authorized", target_type=target_type) ``` Report generation also records its target without redaction: ```python audit(cfg_dir, "report.generate", target=target or "", f ...[truncated 2250 chars]
Remediation
## Remediation Suggestions 1. Redact all audit fields before serialization: ```python entry.update(redact_value(fields)) ``` Alternatively, redact selected fields explicitly before calling `audit()`. 2. Reject URLs containing user information unless there is a documented requirement to support them. 3. Remove or redact query strings and fragments from logged targets. 4. Change report-generation audit logging to use `redact_text(target)`. 5. Apply restrictive permissions when creating the configuration directory and audit file, such as directory mode `0700` and file mode `0600` on POSIX systems. 6. Redact records again during audit export as defense in depth. 7. Add tests proving that credentials are absent from both `audit.log` and exported JSONL files. 8. Document a retention and deletion policy for audit records because security-testing targets may themselves be sensitive.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/yotta_security_testing.py:669
Finding
Scan Metadata Bypasses Report Credential Redaction## Vulnerability Details **File Location**: `scripts/yotta_security_testing.py:669-673` and `scripts/yotta_security_testing.py:758-765` **Vulnerability Type**: Incomplete sensitive-data redaction **Risk Level**: Medium ### Vulnerable Code The Markdown renderer inserts scan metadata directly: ```python for sc in scans: if not isinstance(sc, dict): continue tool = sc.get("tool") or "-" kind = sc.get("kind") or "-" verdict = sc.get("verdict") or "-" ref = sc.get("reference") or sc.get("report") or "-" lines.append("| %s | %s | %s | `%s` |" % (tool, kind, verdict, ref)) ``` The JSON report also includes the original scan array: ```python if args.json: report = { "tool": "%s %s v%s" % (CN_NAME, TOOL_NAME, VERSION), "target": redact_text(target), "generated_at": generated_at, "summary": counts, "scans": scans or [], "findings": findings, } ``` ### Technical Analysis The implementation recursively applies `redact_value()` to every finding and calls `redact_text()` for the main target. However, the optional `scans` array is neither recursively redacted nor escaped before being rendered. In Markdown output, the `tool`, `kind`, `verdict`, and `reference` or `report` fields are interpolated directly into a table. In JSON output, the entire original `scans` array is copied into the generated report. As a result, sensitive values such as authenticated report URLs, API tokens, cookies, usernames, passwords, or private internal references can bypass the report's credential-redaction mechanism. This conflicts with the report's assertion that sensitive credentials have been redacted. Direct Markdown interpolation also permits untrusted scan metadata to alter table formatting or inject Markdown links and embedded image references. The confirmed security issue is the redaction bypass; no automatic browser or network execu ...[truncated 1098 chars]
Remediation
## Remediation Suggestions 1. Redact scan metadata immediately after parsing: ```python scans = redact_value(scans) if scans else [] ``` 2. Use only the redacted copy for Markdown rendering, JSON output, and audit records. 3. Apply `redact_text()` individually to every string interpolated into Markdown as defense in depth. 4. Escape Markdown table delimiters, line breaks, links, and image syntax in untrusted scan metadata. 5. Define and validate a strict schema for scan entries rather than accepting arbitrary dictionaries. 6. Add regression tests covering passwords, authorization headers, cookies, bearer tokens, URL user information, query-string tokens, long hexadecimal strings, and Base64-like secrets in every scan field. 7. Update report wording so it claims complete redaction only after all report sections pass through the same redaction pipeline.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (4)

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill appears to require effective capabilities such as shell execution and filesystem read/write while declaring no permissions. That creates a transparency and policy-enforcement gap: reviewers and runtime controls may treat the skill as lower risk than it really is, even though it can modify local files, inspect environment data, and invoke commands. In a security-testing skill, those capabilities are especially sensitive because they can be used to pivot from guidance into actual system-changing behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The documented purpose presents the skill as a methodology and guardrail framework, but the detected behavior includes cross-agent installation and filesystem deployment logic not disclosed in that description. This mismatch is dangerous because users may approve a 'documentation/testing' skill without realizing it can copy itself into agent skill directories and alter the local agent environment. Hidden installation behavior increases the risk of persistence, unintended propagation, and bypass of normal review expectations.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The documented trigger phrases include very broad terms such as 'security test', 'pentest', and especially 'scope check', which can plausibly appear in benign discussion, analysis, or report-writing contexts. Over-broad activation increases the chance the skill is invoked unintentionally, exposing users to security-testing guidance in contexts where it was not explicitly requested.

Vague Triggers

Medium
Confidence
79% confidence
Finding
The trigger phrases include broad everyday language such as '安全测试', '渗透', or '测一下这个站', which can cause the skill to activate in contexts that are ambiguous or insufficiently authorized. For a skill covering offensive security workflows, accidental invocation matters because it may steer conversations toward sensitive testing procedures before authorization has been firmly established. The built-in scope language reduces risk somewhat, but overbroad triggers still widen exposure and increase chances of misuse or policy boundary confusion.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.exposed_secret_literal

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
test/install.test.js:12

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/test_yotta_security_testing.py:526