Back to skill

Security audit

元史 yotta-logs

Security checks for vulnerabilities and agentic risk

Overview

The skill appears purpose-built for local log retrieval, but it needs Review because it searches sensitive cross-agent history and its default redaction can miss secrets embedded in URLs.

Install only if you are comfortable with an agent reading local conversation logs and memory files across supported tools. Prefer explicit --dir, --source, --kind, or --format filters, pin the npm version when using npx, avoid global installation unless you really want every supported agent to load it, and treat output as sensitive because URL-embedded tokens may not be fully redacted.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/yotta_logs.py:118
Finding
Credential-Bearing URLs Bypass Default Secret Redaction<![CDATA[ ## Vulnerability Details **File Location**: `scripts/yotta_logs.py:118-136` **Vulnerability Type**: Sensitive information disclosure through incomplete output redaction **Risk Level**: Medium ### Vulnerable Code ```python def redact(text): """把疑似密钥 / token / 口令打码(默认开启;--no-redact 关闭)。""" if not text: return text text = _PEM_RE.sub("[PRIVATE KEY REDACTED]", text) text = _URL_USERPASS_RE.sub(r"\1\2:***@", text) chunks = _URL_RE.split(text) # 奇数下标为 URL,原文保留(路径不算密钥) out = [] for i, chunk in enumerate(chunks): if i % 2 == 1: out.append(chunk) continue chunk = _KNOWN_KEY_RE.sub("***", chunk) chunk = _JWT_RE.sub("***", chunk) chunk = _BEARER_RE.sub("Bearer ***", chunk) chunk = _ASSIGN_RE.sub(lambda m: m.group(1) + "=***", chunk) chunk = _LONG_TOKEN_RE.sub("***", chunk) out.append(chunk) return "".join(out) ``` ### Technical Analysis The redaction function divides its input into URL and non-URL chunks using `_URL_RE`. Every URL chunk is then appended directly to the result without applying the known-key, JWT, bearer-token, assignment, or long-token redaction rules. The preceding `_URL_USERPASS_RE` only masks conventional URL user information such as: ```text https://user:password@example.com/ ``` It does not protect secrets stored in URL query parameters, fragments, or path components. For example, the following values can remain visible: ```text https://example.com/callback?token=sk-example-secret https://example.com/api/eyJ...eyJ...signature https://example.com/download/very-long-sensitive-token ``` This behavior conflicts with the documented guarantee that search and session output is redacted by default. Because agent session logs commonly include request URLs, callback URLs, signed download links, and debugging output, the flaw can expose credentials even when the user has not selected `--no-redact`. ### Attack Path 1. A se ...[truncated 1310 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not exempt complete URLs from secret detection. Parse each URL and redact its sensitive components before returning it. Recommended hardening steps: 1. Use `urllib.parse.urlsplit`, `parse_qsl`, `urlencode`, and `urlunsplit` to process URLs structurally. 2. Continue masking URL passwords in the authority component. 3. Replace values of sensitive query parameters such as `token`, `key`, `api_key`, `access_token`, `secret`, `signature`, `sig`, `password`, and `auth`. 4. Apply known-key, JWT, bearer-token, and long-token detection to path and fragment components. 5. Preserve ordinary host names and non-sensitive paths so URLs remain useful for historical lookup. 6. Handle malformed URLs conservatively by applying the general redaction expressions to the entire matched value. 7. Add regression tests covering: - API keys in query parameters; - JWTs in paths and fragments; - Signed URLs; - Percent-encoded credentials; - Multiple query parameters; - URL user information; - Benign URLs that should remain readable. A safe implementation should redact the URL before appending it rather than using `out.append(chunk)` directly. ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:108
Finding
Recommended Installation Command Executes an Unpinned Registry Package<![CDATA[ ## Vulnerability Details **File Location**: `README.md:108-120` **Vulnerability Type**: Unpinned remote package retrieval and execution **Risk Level**: Medium ### Vulnerable Code ```text ## Installation Pick any of the four methods below; the order is the recommended priority. Skill files always come from **npm** (GitHub can be slow without a proxy; npm supports mirrors). ### Method 1: npm one-liner (recommended) ```text # Optional China mirror: npm config set registry https://registry.npmmirror.com npx -y @yottameta/yotta-logs --agent <agent-name> # install to the agent's default user-level skills dir npx -y @yottameta/yotta-logs --dir <your-skills-dir> # point to the skills dir itself (e.g. ~/.codex/skills) ``` - `--agent <name>` installs to that agent's default user-level directory; `--list` shows each agent's default directory. - `--dir <path>` installs to the given directory; for agents not in the preset list, point `--dir` at their skills directory. - If the mirror has not synced the new package (404): add `--registry=https://registry.npmjs.org/` (a proxy may be needed in China), or wait for the mirror cache. ``` ### Technical Analysis The recommended installation commands invoke `npx -y` without specifying a package version. Consequently, npm resolves and executes whichever release is associated with the package's current distribution tag at installation time. The bundled `bin/install.js` reviewed in this artifact performs local file-copy installation and does not contain a malicious payload. Nevertheless, the documented command does not guarantee that users will execute this reviewed version. Its effective payload can change after the audit if: - The npm publisher account is compromised; - A malicious release is published; - The package ownership or distribution tag is altered; - A configured mirror serves a modified or stale package; - The package is legitimately updated with unsafe behavior. The `-y` option removes the int ...[truncated 1658 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Pin the installation command to a reviewed release: ```text npx -y @yottameta/yotta-logs@0.3.1 --agent <agent-name> npx -y @yottameta/yotta-logs@0.3.1 --dir <your-skills-dir> ``` Additional supply-chain hardening should include: 1. Publish and document cryptographic integrity hashes for release artifacts. 2. Sign releases and provide instructions for verifying signatures. 3. Protect npm publisher accounts with phishing-resistant multi-factor authentication. 4. Use npm trusted publishing or short-lived publication credentials. 5. Restrict and audit package maintainers and distribution-tag changes. 6. Keep npm and GitHub release versions synchronized. 7. Warn users that third-party mirrors introduce a separate trust boundary. 8. Recommend downloading and verifying an immutable release artifact in high-security environments. 9. Avoid running installation commands under root or administrator accounts. 10. Consider documenting `npm view @yottameta/yotta-logs version` and package-integrity inspection before execution. These measures ensure that the installed and executed package more closely matches the artifact that was reviewed. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (60)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description says the skill's purpose is to read and analyze local history/memory files for cross-session retrieval, explicitly stating it only reads local logs and does not modify or delete anything. The actual code does not implement any log parsing, search, historical retrieval, JSON/SQLite/Markdown reading, or conversation analysis. Instead, it is an installer utility whose primary function is to copy the package into various agent skill directories. This is a materially different purpose and includes undeclared write/install capabilities that directly contradict the declared read-only boundary.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description presents a read-only historical log retrieval skill that searches local conversation/memory files. The supplied code does not implement any log parsing, retrieval, JSON/SQLite/Markdown analysis, or session-history lookup. Instead, it is purely an installer script that writes to the filesystem by creating directories, copying the skill contents, and deleting the copied .git directory. This also contradicts the stated boundary of not modifying files. The primary purpose and behavior are therefore materially different from the declared description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description says this skill should read local conversation/memory logs in several formats and help trace prior discussions without modifying files. The actual code chunk does not implement or test any log parsing, retrieval, history lookup, or cross-session context analysis. Instead, it tests an installation command that copies skill files into a destination directory and checks error messages for installer arguments. That is a materially different primary purpose. It also involves filesystem modification behavior (creating/removing temp directories and asserting installed files), which conflicts with the declared read-only scope.

Ae1

High
Category
analysis-evasion
Content
python3 scripts/yotta_logs.py locate
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/yotta_logs.py locate
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/yotta_logs.py locate
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/yotta_logs.py locate
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/yotta_logs.py locate
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/yotta_logs.py locate
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/yotta_logs.py locate
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/yotta_logs.py locate
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/yotta_logs.py locate
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/yotta_logs.py locate
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 scripts/yotta_logs.py locate
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The manifest frames yotta-logs as a skill that only reads local conversation and memory files, explicitly stating it does not modify or delete. This installer creates directories and copies the package into target locations, which is a write operation outside the described read-only behavior.

Context-Inappropriate Capability

High
Confidence
94% confidence
Finding
The `--global` mode writes the package into every known agent skill directory under the user's home/config paths, which can cause unexpected broad deployment across unrelated tools. In the context of a skill advertised as local log retrieval, mass installation increases blast radius if the package is later found harmful or is accidentally invoked by multiple agents, making the behavior more dangerous than a single explicit-target install.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The skill is described as a read-only local log retrieval capability, but the installer writes files into agent skill directories, altering the local agent environment. While installation scripts normally perform writes, this still expands behavior beyond the stated runtime scope and can introduce persistence across agents if a user runs it without understanding the breadth of installation.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
install_to() {
  mkdir -p "$1/$SKILL_NAME"
  cp -r "$SOURCE_DIR/." "$1/$SKILL_NAME/"
  rm -rf "$1/$SKILL_NAME/.git"
  echo "installed -> $1/$SKILL_NAME"
}
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Env Variable Harvesting

High
Category
Data Exfiltration
Content
def _run(args, inp=None, env=None, cwd=None):
    e = dict(os.environ)
    if env:
        e.update(env)
    return subprocess.run(
Confidence
60% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
def _run(args, inp=None, env=None, cwd=None):
    e = dict(os.environ)
    if env:
        e.update(env)
    return subprocess.run(
Confidence
60% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The activation language is broad: it triggers whenever a user references previous content, parent sessions, or historical context. For a skill that searches local conversation and memory logs across agents, over-broad activation can cause unnecessary access to sensitive historical data, increasing the chance of privacy leakage or over-collection beyond user intent. The skill context makes this more sensitive because the underlying data may include cross-session secrets, credentials, or private reasoning traces.

Skill Enumeration

Medium
Category
Agent Snooping
Content
```text
# Optional China mirror: npm config set registry https://registry.npmmirror.com
npx -y @yottameta/yotta-logs --agent <agent-name>      # install to the agent's default user-level skills dir
npx -y @yottameta/yotta-logs --dir <your-skills-dir>   # point to the skills dir itself (e.g. ~/.codex/skills)
```
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding
The README instructs users to execute `npx -y @yottameta/yotta-logs` without pinning a version. That causes installation and execution of whatever package version is current in the registry at runtime, creating a supply-chain risk if a future release is compromised, maliciously updated, or unexpectedly breaking. Because this is an install command users are likely to copy-paste, the exposure is real even though the file is only documentation.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding
This second `npx -y @yottameta/yotta-logs` example is likewise unpinned, so it has the same supply-chain exposure: users will fetch and run the latest published package rather than a reviewed version. In a skill ecosystem, install commands are especially sensitive because they execute package code during installation and setup.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

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