Back to skill

Security audit

YouOS

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a coherent personal email copilot, but it needs Review because private email and context can be sent to Claude in ways that conflict with its local-first and local-only claims.

Install only after reviewing the cloud-model paths. If you require strict local-only operation, do not configure Claude credentials and verify or patch the streaming draft and fact-extraction paths before using the web UI. Keep the server bound to localhost with a PIN, and be deliberate about the setup prompts for background ingestion and nightly self-improvement.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup_wizard.py:829
Finding

Setup Defaults Routine Review Drafts to External Claude Processing Without Explicit Consent

Content
View full analysis
bool: """Resolve whether to use the local model for Review Queue drafts based on config. review.draft_model: 'claude' (default) — always use Claude (faster) 'local' — always use local Qwen adapter 'auto' — use local if adapter is ready, else Claude """ model_pref = get_review_draft_model() if model_pref == "local": return True if model_pref == "auto": return _adapter_available() return False # 'claude' ``` ```python # app/generation/service.py:1472-1479 def _call_claude_cli(prompt: str, *, max_tokens: int = 300) -> str: # noqa: ARG001 # Note: claude CLI --print does not support --max-tokens; use -p to pass prompt cmd = ["claude", "--print", "-p", prompt] result = _run_subprocess(cmd, timeout=SUBPROCESS_TIMEOUT) if result.returncode != 0: stderr = result.stderr.strip() raise RuntimeError(f"claude CLI failed (exit {result.returncode}): {stderr}") return result.stdout.strip() ``` ### Technical Analysis The setup wizard writes `review.draft_model: claude` unless that setting already exists. It does not ask the user to authorize external processing before selecting this value. The Review Queue interprets `claude` by returning `False` from `_resolve_use_local_model()`. Draft generation then assembles a prompt containing privacy-sensitive material, potentially including: - The inbound email and se ...[truncated 2448 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
app/core/facts_extractor.py:359
Finding

Strict Local-Only Configuration Does Not Prevent Claude-Based Fact Extraction

Content
View full analysis
list[dict]: """Call Claude CLI to extract facts from unstructured notes. Only intended as a fallback when rule-based extraction returns nothing. Returns a list of fact dicts (type, key, fact, confidence). """ prompt = ( "Extract structured facts from the note below about a contact or project.\n" "Return ONLY a JSON array of objects, each with keys:\n" ' "type" → one of: contact, project, user_pref\n' ' "key" → email address for contact facts, project name for project facts, ' '"default" for user_pref\n' ' "fact" → short descriptive string (e.g. "Prefers short replies")\n\n' f"Sender email: {sender_email or 'unknown'}\n" f"Note: {note}\n\n" "JSON array:" ) try: result = subprocess.run( ["claude", "--print", "-p", prompt], capture_output=True, text=True, timeout=30, ) if result.returncode != 0: return [] text = result.stdout.strip() json_match = re.search(r"\[.*\]", text, re.DOTALL) if not json_match: return [] ``` The fallback is reached by the following control flow: ```python # app/core/facts_extractor.py:531-534 candidates = extract_facts(note, sender_email=sender_email, project_name=project_name) if not candidates: candidates = extract_facts_llm(note, sender_email=sender_email) ``` ### Technical Analysis The application first applies local regular-expression rules to feedback or re ...[truncated 2378 chars]
Remediation
View remediation
Vulnerability Patterns
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • 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 (213)

Tainted flow: 'email' from input (line 186, user input) → subprocess.run (code execution)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

External input (network, user) flows to a code execution sink. This enables remote code execution or command injection.

Content

Scanner excerpt · scripts/setup_wizard.py (reported line 250)May include surrounding context.

python
verified = []
    for email in emails:
        try:
            result = subprocess.run(
                ["gog", "gmail", "search", "in:sent", "--account", email, "--limit", "1", "--json"],
                capture_output=True,
                text=True,

Tainted flow: 'email' from input (line 186, user input) → subprocess.run (code execution)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

External input (network, user) flows to a code execution sink. This enables remote code execution or command injection.

Content

Scanner excerpt · scripts/setup_wizard.py (reported line 299)May include surrounding context.

python
print(f"\nIngesting {email} ({query}, max_threads={thread_cap})...")
        local_threads = 0
        local_pairs = 0
        result = subprocess.run(
            [
                sys.executable,
                str(ROOT_DIR / "scripts" / "ingest_gmail_threads.py"),

Tainted flow: 'email' from input (line 186, user input) → subprocess.Popen (code execution)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

External input (network, user) flows to a code execution sink. This enables remote code execution or command injection.

Content

Scanner excerpt · scripts/setup_wizard.py (reported line 374)May include surrounding context.

python
safe_email = email.replace("@", "_at_").replace(".", "_")
                log_path = log_dir / f"ingest-background-{safe_email}-{stamp}.log"
                with open(log_path, "w", encoding="utf-8") as logf:
                    proc = subprocess.Popen(
                        [
                            sys.executable,
                            str(ROOT_DIR / "scripts" / "ingest_gmail_threads.py"),

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% 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).

Content

Scanner excerpt · PRIVACY.md (reported line 40)May include surrounding context.

Option 1: Delete the database

bash
rm ~/Projects/youos/var/youos.db

Option 2: Delete all YouOS data

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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).

Content

Scanner excerpt · PRIVACY.md (reported line 45)May include surrounding context.

Option 2: Delete all YouOS data

bash
rm -rf ~/Projects/youos/var/
rm -rf ~/Projects/youos/data/
rm -rf ~/Projects/youos/models/adapters/latest/
rm ~/Projects/youos/configs/persona_analysis.json

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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).

Content

Scanner excerpt · PRIVACY.md (reported line 46)May include surrounding context.

Option 2: Delete all YouOS data

bash
rm -rf ~/Projects/youos/var/
rm -rf ~/Projects/youos/data/
rm -rf ~/Projects/youos/models/adapters/latest/
rm ~/Projects/youos/configs/persona_analysis.json

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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).

Content

Scanner excerpt · PRIVACY.md (reported line 47)May include surrounding context.

Option 2: Delete all YouOS data

bash
rm -rf ~/Projects/youos/var/
rm -rf ~/Projects/youos/data/
rm -rf ~/Projects/youos/models/adapters/latest/
rm ~/Projects/youos/configs/persona_analysis.json

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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).

Content

Scanner excerpt · PRIVACY.md (reported line 53)May include surrounding context.

Option 2: Delete all YouOS data

bash
rm -rf ~/Projects/youos/var/
rm -rf ~/Projects/youos/data/
rm -rf ~/Projects/youos/models/adapters/latest/
rm ~/Projects/youos/configs/persona_analysis.json

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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).

Content

Scanner excerpt · PRIVACY.md (reported line 45)May include surrounding context.

Option 2: Delete all YouOS data

bash
rm -rf ~/Projects/youos/var/
rm -rf ~/Projects/youos/data/
rm -rf ~/Projects/youos/models/adapters/latest/
rm ~/Projects/youos/configs/persona_analysis.json

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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).

Content

Scanner excerpt · PRIVACY.md (reported line 46)May include surrounding context.

Option 2: Delete all YouOS data

bash
rm -rf ~/Projects/youos/var/
rm -rf ~/Projects/youos/data/
rm -rf ~/Projects/youos/models/adapters/latest/
rm ~/Projects/youos/configs/persona_analysis.json

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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).

Content

Scanner excerpt · PRIVACY.md (reported line 47)May include surrounding context.

bash
rm -rf ~/Projects/youos/var/
rm -rf ~/Projects/youos/data/
rm -rf ~/Projects/youos/models/adapters/latest/
rm ~/Projects/youos/configs/persona_analysis.json

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% 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).

Content

Scanner excerpt · PRIVACY.md (reported line 48)May include surrounding context.

rm -rf ~/Projects/youos/var/ rm -rf ~/Projects/youos/data/ rm -rf ~/Projects/youos/models/adapters/latest/ rm ~/Projects/youos/configs/persona_analysis.json

text

**Option 3: Remove YouOS entirely**

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% 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).

Content

Scanner excerpt · PRIVACY.md (reported line 53)May include surrounding context.

Option 3: Remove YouOS entirely

bash
rm -rf ~/Projects/youos

Data retention

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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).

Content

Scanner excerpt · README.md (reported line 255)May include surrounding context.

text
GET    /api/facts          — list all facts (optional ?type= filter: contact | project | user_pref)
POST   /api/facts          — create or upsert a fact
DELETE /api/facts/{id}     — delete a fact by id

Example fact types:

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description centers on a personal email copilot that learns from message/document exports and drafts replies in the user's voice. This code chunk instead implements a standalone facts-management API: it lists facts, creates or upserts facts, and deletes facts in a SQLite table. While such a memory store could be a supporting component of a larger drafting system, this chunk's actual behavior is materially different from the declared primary purpose and omits the core advertised capabilities such as import from Gmail/Docs/WhatsApp, style learning, and draft generation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The code is broadly related to an email drafting copilot and a self-improving workflow: it generates drafts, records user edits, and uses feedback to improve or analyze behavior. However, the supplied chunk does substantially more than the declared description suggests. It exposes HTML/UI routes for feedback, about, bookmarklet installation, and a Gmail popup; processes and stores feedback analytics; updates corpus quality scores; classifies senders; and performs fact extraction from reply pairs and feedback notes. These are meaningful undeclared capabilities, especially the bookmarklet/extension support and database-backed fact extraction/quality-scoring pipeline. So while the functionality is adjacent to the declared purpose, the description does not accurately capture several significant behaviors present in this code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description emphasizes a personal communication copilot that learns from exported data sources and drafts replies in the user's voice. This code chunk instead implements a backend history-reading route: it queries a local SQLite table named draft_history and returns stored items and counts. That may support a broader copilot product, but the chunk's primary behavior is database-backed history retrieval, which is not reflected in the declared purpose. There are no triggers or permissions to compare, but the actual capability shown here is materially narrower and different from the stated learning/drafting functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The code is related to the general domain of an email drafting copilot and self-improving workflow, so it is not wholly unrelated. It does generate drafts, review prior message pairs, and collect feedback to improve the system, which aligns partially with the description. However, the supplied chunk does substantially more specific and operational work than the declared description states: it exposes multiple review-queue API endpoints, streams draft generation results, persists review feedback and streak metrics in SQLite, launches background subprocesses for sender-profile rebuilding and an autoresearch optimization pipeline, and provides an explicit adapter-vs-base comparison endpoint. These are meaningful capabilities and triggers not represented in the declared purpose, and the 'local-first' framing is also only partially accurate because the code can use non-local drafting modes (e.g. config pref 'claude'). Therefore the description does not accurately represent this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The draft and retrieval endpoints are broadly consistent with an email-style writing copilot that uses stored context to generate replies and explain precedents. However, the code chunk also includes substantial undeclared administrative and data-management capabilities: health checks, readiness checks, config summary, startup safety reporting, snapshot listing/creation, and snapshot restoration of the database. These are materially beyond the declared end-user purpose of a local-first personal email copilot. The restore endpoint in particular can alter application data state, which is a significant capability not reflected in the description or permissions. While some operational endpoints may be supporting infrastructure, the explicit data snapshot and restore API constitutes a notable undeclared behavior, so this is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The code is related to the broader product described: it supports ingestion, model fine-tuning, benchmarking, and statistics for a personalized email assistant. So the overall domain is aligned. However, the declared description emphasizes drafting replies and learning the user's style from exports, while this code chunk primarily implements administrative and operational backend routes. It includes undeclared capabilities such as creating API tokens, installing/starting a launchd background service, mutating feature flags and identity settings, and serving dashboard/settings/onboarding pages. Those are materially broader than a simple drafting copilot description and represent admin/system-management behavior not reflected in the declared purpose. Therefore this chunk is a mismatch, though not because it is unrelated—rather because it exposes significant undeclared operational capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description is about an end-user email copilot that learns from exported personal communications and drafts replies in the user's voice. The supplied code chunk does not ingest Gmail/Docs/WhatsApp data, analyze writing style, or generate email drafts. Instead, it is an internal configuration mutation utility for experimentation/optimization: it reads YAML configs, exposes mutable tuning surfaces, applies numeric or template mutations, reverts changes, and writes configs back to disk. While prompt-template tuning could support the broader product, this chunk's actual primary purpose is autoresearch/config optimization, which is materially different from the declared user-facing functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description is about an end-user communication copilot for drafting email replies in the user's voice based on imported personal data. The supplied code does not perform style learning, ingest Gmail/Docs/WhatsApp exports, draft replies, or assist with messaging workflows. Instead, it runs an internal optimization process for system configuration: selecting mutable surfaces, applying mutations, evaluating candidate configurations, reverting regressions, logging results to a database, and writing JSONL summaries. These are materially different capabilities and indicate a distinct primary purpose from the declared description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is about a personal email copilot that learns writing style from user communication sources and drafts replies. The supplied code instead implements database persistence for an unrelated 'autoresearch' run log. Its primary purpose is schema creation and insertion of experiment iteration records in SQLite. There is no functionality related to email, message drafting, learning writing style, or accessing Gmail, Google Docs, or WhatsApp exports. This is a clear description-to-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is about an end-user communication assistant that ingests personal exports and drafts email replies in the user's writing style. The supplied code does not draft emails, learn writing style, access Gmail/Docs/WhatsApp data, or implement a personal communication workflow. Instead, it is an internal evaluation/scoring module for an autoresearch or optimization system, focused on metrics aggregation and config comparison. This is a materially different primary purpose, so the description does not accurately represent the code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The code substantially overlaps with the declared purpose: it provides commands to ingest Gmail and WhatsApp data, draft replies in the user's style, collect feedback, run fine-tuning/evaluation, and launch a UI for a self-improving workflow. However, the implementation also exposes several significant capabilities not reflected in the description, especially operational/admin features: installing a background service, serving a web app, creating and revoking API tokens for a browser extension, exporting/importing archives, and creating/restoring database snapshots. These are more than incidental implementation details because they directly manage access, persistence, and deployment. Additionally, while the description says the tool learns from Gmail, Google Docs, and WhatsApp exports, this code chunk only clearly shows Gmail and WhatsApp ingestion; no Google Docs ingestion is evidenced here. Therefore the description is only partially accurate and omits material capabilities while claiming at least one source not supported by the supplied code chunk.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
app/main.py:119