Back to skill

Security audit

Agent OS Asset

Security checks for vulnerabilities and agentic risk

Overview

The skill can reorganize and index local files, but it discloses that and requires explicit opt-ins for moves, deletion, indexing, background sync, and remote services.

Install only from a source you trust, review the selected root and scope before running it, and use plan-only or dry-run first. Treat --execute-decisions, --execute-extraction, --execute-sync, --execute-index, --auto-keep, --allow-semantic-rerank, --enable-apply, and LaunchAgent install as high-impact choices. Do not enable provider-backed summaries or embeddings unless you are comfortable sending bounded note/index text to that provider.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T08 · Insecure Dependencies

Warning
Location
README.md:20
Finding
Unpinned Remote Packages and Repository Content Are Executed Locally<![CDATA[ ## Vulnerability Details **File Location**: `README.md:20`, `README.md:46`, `references/security-boundaries.md:39`, `skills/kb-review/SKILL.md:142` **Vulnerability Type**: Unpinned dependency and remote package execution **Risk Level**: Medium ### Vulnerable Code `README.md:20`: ```bash npx skills add lee-agi/agent-os-asset -g -y ``` `README.md:46`: ```bash uvx --from pytest pytest -q ``` `references/security-boundaries.md:39`: ```bash PYTHONDONTWRITEBYTECODE=1 uvx --from pytest pytest -q -p no:cacheprovider ``` `skills/kb-review/SKILL.md:142`: ```bash uvx --from pytest pytest -q test/kb_review ``` ### Technical Analysis The documented commands resolve remote npm, repository, or Python package content without an immutable version, commit identifier, lockfile, or integrity hash. The `npx` command additionally uses `-g -y`, creating an unattended global installation path. The effective code executed or installed can therefore change after this Skill version has been audited. The `uvx --from pytest` commands similarly resolve a mutable package version and execute its console entry point in a generated environment. This does not establish that the current upstream packages are malicious. The vulnerability is the lack of reproducible dependency selection and integrity verification, which exposes users to package-registry compromise, upstream account takeover, malicious future releases, and repository reference changes. ### Attack Path 1. An attacker compromises the relevant package registry entry, upstream repository, maintainer account, or dependency publication process. 2. The attacker publishes malicious content under the mutable package or repository reference used by the documented command. 3. A user follows the project documentation and runs the `npx` or `uvx` command. 4. The package manager downloads the changed content without verifying it against a project-controlled lockfile or expected digest. 5. The downloaded package or install ...[truncated 740 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every remotely resolved package to an exact, reviewed version: ```bash uvx --from 'pytest==<reviewed-version>' pytest -q ``` 2. Pin repository installation sources to an immutable commit hash or signed release rather than a mutable owner/repository reference. 3. Publish and verify cryptographic checksums or signatures for installed Skill releases. 4. Add appropriate lockfiles and require integrity-checked, reproducible dependency restoration in release and CI workflows. 5. Avoid unattended global installation. Prefer an isolated local environment and remove `-g -y` unless global installation is strictly necessary and separately approved. 6. Document the exact package version, repository commit, expected digest, and provenance verification procedure. 7. Where possible, separate download from execution so users can inspect and verify retrieved content before running it. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (27)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if debounce_seconds:
            time.sleep(debounce_seconds)
        command = adapter_command(root, scope, cleanup_tool, auto_keep=auto_keep)
        result = subprocess.run(command, cwd=root, check=False, text=True, capture_output=True)
        payload = command_json(result.stdout)
        state = load_state(root)
        state["last_runner_at"] = utc_now()
Confidence
93% confidence
Finding
The script executes a user-supplied or externally selected cleanup tool path with the current interpreter, and only checks that the file exists. In a security-sensitive automation context, that enables arbitrary code execution if an attacker can influence --cleanup-tool, the default adapter file, or the repository contents from which it is loaded.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
audit_command = [sys.executable, str(cleanup_tool), "--audit-agent-assets"]
            if scope != ".":
                audit_command.extend(["--scope", scope])
            audit_result = subprocess.run(audit_command, cwd=root, check=False, text=True, capture_output=True)
            audit = command_json(audit_result.stdout)
            summary = audit.get("summary", {})
            blockers = ("candidate", "review", "missing_source", "missing_semantic", "final_pii", "delete_failed")
Confidence
92% confidence
Finding
The audit step re-executes the same externally controlled cleanup tool for a second mode, again trusting only file existence. If an attacker replaces or redirects that adapter, the auto-sync runner will repeatedly execute attacker-controlled Python within the user's session, amplified by LaunchAgent persistence.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill clearly orchestrates filesystem reads/writes, shell execution, local server behavior, indexing, and potentially provider-backed network operations, yet it declares no explicit permissions or capability boundaries in machine-readable metadata. That mismatch can cause a host runtime or reviewer to underestimate the skill's power, increasing the risk of over-privileged execution and unsafe consent around destructive actions like file moves, indexing, or sync installation.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill can move an entire repository to ~/.Trash when a decision file contains delete and the operator supplies --allow-delete-repo. That capability exceeds the stated repository summarization/review purpose and turns a metadata-generation workflow into a destructive file operation, increasing the risk of unintended data loss if a crafted or mistaken decision file is applied.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
The CLI surface exposes --allow-delete-repo even though the skill description is about designing, auditing, and modernizing historical folders into reviewable agent assets. That mismatch is dangerous because users and higher-level agents may invoke the tool under the assumption it is non-destructive, while a hidden or unexpected flag enables whole-repository removal.

Intent-Code Divergence

High
Confidence
99% confidence
Finding
The help text says execute mode is non-destructive, but execute mode in combination with applied decisions can ultimately move the repository to Trash. This misleading safety claim can cause operators or orchestrating agents to choose execute mode without recognizing that destructive behavior is reachable, undermining informed consent and safe automation.

Description-Behavior Mismatch

High
Confidence
95% confidence
Finding
The skill contains a full decision-application path that can mark assets for deletion and then move source and semantic files, including directories for code projects, to Trash. In the context of a modernization/audit skill handling historical folders, this is dangerous because the capability goes beyond analysis and can irreversibly alter or remove user data if the decisions file is wrong, malicious, or applied unintentionally.

Context-Inappropriate Capability

Medium
Confidence
87% confidence
Finding
The code performs OS-level trash operations through Finder/AppleScript or a fallback move into `~/.Trash`, creating a direct file-deletion capability on the host. Even though there are boundary checks, this still materially increases the blast radius of any mistaken or malicious decision input because the skill is empowered to affect real user files outside a purely analytical workflow.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
The skill reads AGENTS.md and CLAUDE.md from source repositories and incorporates their contents into generated context, even while labeling them as untrusted evidence. In this skill's stated context—explicitly not responding to embedded instructions in source documents—ingesting instruction-bearing files is risky because it can re-surface adversarial guidance into downstream review artifacts and influence human or agent decision-making despite the disclaimer.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
This skill introduces a review workbench and bundled loopback server capabilities beyond simple extraction/conversion, increasing the attack surface from passive document handling to interactive decision export and execution flows. Even though the text includes safeguards like read-only default, same-origin POST, Host/Origin validation, and explicit capabilities, embedding server/UI behavior in a conversion skill can encourage unintended deployment, privilege creep, or unsafe integration by downstream agents.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The file declares a distinct skill identity and behavior ('Agent Readable Doc' for document conversion) that does not align with the surrounding skill metadata for historical-folder modernization into privacy-aware Agent Assets. This kind of purpose drift is dangerous because it can cause the agent to invoke the wrong capability, bypass expected review boundaries, or process documents under a weaker or mismatched trust model than the enclosing skill intends.

Context-Inappropriate Capability

Medium
Confidence
70% confidence
Finding
The legacy Office and PDF paths invoke complex third-party parsers and converters (LibreOffice, Ghostscript, pdftotext, Tesseract) on untrusted input files. Even though the Python code uses argument lists safely, these tools have historically had parser vulnerabilities, so feeding attacker-controlled documents into them can create a real local attack surface inconsistent with a privacy-focused assetization skill.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The function writes normalized source text, extracted evidence, file metadata, and search terms into durable Markdown and manifest outputs, effectively republishing source content for later retrieval. In a skill explicitly framed as privacy-aware and not for ordinary file reading, this broad materialization increases the risk of over-collection, unauthorized secondary use, and accidental exposure of sensitive document contents.

Description-Behavior Mismatch

Medium
Confidence
84% confidence
Finding
The embedded guidance tells downstream users to use the generated asset for 'locating or understanding' the source document, which broadens the skill from asset indexing into substitute reading of document content. That mismatch can cause agents or users to rely on derived assets as a general document-reading surface, undermining the stated boundary that the skill is not for ordinary file reading and increasing privacy and policy drift.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The script can send note-derived content to a remote OpenAI-compatible endpoint when opt-in environment variables are set. Even though this is gated behind explicit configuration and has local fallbacks, it still creates a real data-exfiltration path for potentially sensitive note content, which is in tension with the skill's privacy-aware/local indexing purpose.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
The code reads remote endpoint and API key configuration from environment variables to enable outbound summarization. This is not credential theft by itself, but it enables network transmission capabilities that may surprise users of a tool presented as local/privacy-aware, especially if deployed in environments where these variables are already populated.

Description-Behavior Mismatch

Medium
Confidence
77% confidence
Finding
This module sends query text and document-derived text to an external embedding provider, which can conflict with the skill's stated privacy-aware and non-ordinary-file-reading scope. If sensitive historical-folder content is embedded without strong user awareness and filtering, private data may be disclosed to a third party.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill describes installing and removing per-directory macOS LaunchAgents for automatic sync, which are persistent system-level changes that continue acting after the session ends. Although the skill requires user-triggered commands, it does not present a prominent user-facing warning about persistence, background execution, and the implications of monitoring directories over time.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill allows final indexing and separately approved provider-backed reranking, both of which may expose document-derived content or metadata beyond the immediate review context. While there are safety gates later in the document, the user-facing invocation path does not prominently warn that indexing broadens local data availability and that reranking can send content to an external provider.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
At the point where the repository is moved to Trash, the code performs the action without an additional runtime prompt or strong user-facing warning. In an automation context, especially where decision files are generated or supplied externally, lack of just-in-time confirmation materially increases the chance of accidental destructive execution.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The destructive execution path proceeds from applied decisions to actual trash operations without any built-in user-facing confirmation checkpoint in the code path itself. That makes operator error, stale decisions, or maliciously crafted decision files significantly more dangerous because a single execute run can remove user content without a last-mile consent barrier.

Missing User Warnings

Low
Confidence
71% confidence
Finding
The extraction flow can archive original user files by moving them into `Archived/` during normal execution, but the code path itself does not enforce a clear interactive warning or confirmation before relocation. Although less severe than deletion because the files remain recoverable, it still changes user data layout and may surprise users in a tool framed partly as audit/review oriented.

Missing User Warnings

Medium
Confidence
78% confidence
Finding
The script persists transformed content and metadata into new outputs without any built-in disclosure, consent checkpoint, or visible warning that source text is being copied into agent-readable artifacts. In privacy-sensitive archival workflows, silent persistence creates a meaningful risk of users misunderstanding data handling, leading to unreviewed replication of confidential material into broader search/index surfaces.

Vague Triggers

Medium
Confidence
90% confidence
Finding
This skill enables implicit invocation without any visible trigger constraints, exclusions, or approval boundaries. Because the skill is designed to access a local second-brain knowledge base, automatic routing could expose note content or metadata in contexts the user did not explicitly intend, especially if prompt routing is overly broad or influenced by surrounding conversation.

Persistent Context Injection

Medium
Category
Memory Poisoning
Content
Learn only from the latest review directory explicitly selected by the user. Do not turn one directory into a universal allowlist or denylist; prefer reusable cross-directory rules. The only exception is an explicit article-ID allowlist matched exactly by `source_path`. / 每轮只从用户明确指定的最新审查目录学习。不要把单个目录固化成通用白名单或黑名单;优先提炼跨目录可复用规则。唯一例外是按 `source_path` 精确匹配的显式文章 ID 白名单。

When an edited `decision` conflicts with the old `reason`, reread safely accessible evidence and rewrite the reason. If full or sampled evidence still cannot distinguish `0` from `1`, output a confirmation item instead of learning a permanent rule. / 当人工 `decision` 与旧 `reason` 冲突时,重新读取可安全访问的证据并改写 reason。若全文或采样后仍无法区分 `0` 与 `1`,输出待确认项,不固化规则。

## Explicit Article IDs To Keep / 显式保留文章 ID
Confidence
84% confidence
Finding
The file explicitly instructs the agent to learn reusable cross-directory rules from prior human-edited review decisions, creating persistent behavioral influence from historical data. Even though it limits learning to the latest user-selected review directory and warns against universal allow/deny lists, it still authorizes durable rule formation that can bias future classifications in ways the current user may not expect or fully audit.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/asset_pipeline.py:38

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/mixed_folder_adapter.py:118

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/review_workbench_server.py:113

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
skills/agent-readable-doc/scripts/materialize_agent_assets.py:71

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
test/agent_os_asset/test_adapter_security.py:21

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
test/agent_os_asset/test_asset_pipeline.py:22

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
test/agent_os_asset/test_auto_sync.py:24

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
test/agent_os_asset/test_mixed_folder_adapter.py:21

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
test/agent_os_asset/test_pipeline_security.py:26

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
test/agent_os_asset/test_review_workbench.py:21

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
test/agent_readable_doc/support.py:29

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
test/kb_review/test_kb_review.py:18

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
test/second_brain/test_asset_index_registry.py:23

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
test/second_brain/test_embedding_rerank.py:22

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
test/second_brain/test_public_release_contract.py:22

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
test/second_brain/test_retrieval_quality.py:23

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
test/second_brain/test_second_brain_index.py:16