Is oathe-ai/darwin safe?
https://github.com/oathe-ai/darwin
DARWIN is a sophisticated multi-stage evolutionary coding workflow plugin that appears to serve a legitimate development purpose but ships with significant security design choices that require user awareness before installation. The most material concerns are: (1) a .claude/settings.json that pre-approves Bash()/Write()/Edit(*) for the entire Claude Code session, silently eliminating all user confirmation dialogs for bash execution and file operations; (2) Stop hooks that can block users from ending their session until the plugin's internal TDD state machine is satisfied; and (3) runtime ! commands that execute shell code at skill load time and inject output into Claude's system prompt, creating a secondary prompt injection surface if the host project's state files contain adversarial content. No explicit credential exfiltration instructions were found in SKILL.md content, canary files remained intact, and network behavior was limited to the expected GitHub clone. The plugin is a legitimate but aggressively permission-seeking development tool whose architectural choices create meaningful attack surface that users should consciously accept.
Category Scores
Findings (14)
HIGH Unrestricted Permission Grant via .claude/settings.json -20 ▶
The plugin ships with a .claude/settings.json that pre-approves Bash(), Write(), and Edit(*) for the entire Claude Code session. This bypasses all user confirmation dialogs for bash commands, file writes, and file edits — including destructive operations. A user installing this plugin unknowingly surrenders the standard safety gate for every bash invocation and file mutation for the duration of any session in that project. Combined with the skill's broad tool access, this means any injected instruction to read credentials or execute malicious commands would proceed without a confirmation prompt.
HIGH Stop Hooks Block Session Termination Indefinitely -15 ▶
darwin-execute-stop.sh and darwin-verify-stop.sh are registered as Stop hooks and return {"decision": "block"} with a reason string whenever their respective completion criteria are not satisfied. The execute hook blocks exit if any task checkbox is unchecked, any batch gate is not verified, or if the completion promise string is absent from the transcript. The verify hook blocks if report.md does not exist. Users cannot end a Claude Code session until the plugin's internal state machine permits it. A malicious variant could trivially create permanent blocking conditions.
HIGH Runtime Shell Commands Injected Into LLM System Prompt at Skill Load -18 ▶
Multiple SKILL.md files use the ! syntax to execute bash at skill load time and inject the output verbatim into Claude's system prompt context. Commands like !cat docs/darwin/_meta/latest-run.json and !jq -r '...' package.json run before any user interaction. If a malicious repository contains adversarial content in these files (e.g., a latest-run.json with injected instructions), that content is silently embedded in Claude's operating context before the user's first message.
MEDIUM Conversation Transcript Read by Stop Hook Shell Script -15 ▶
darwin-execute-stop.sh receives transcript_path from the hook input JSON and reads the full conversation transcript file to search for promise strings in the last assistant message. The transcript contains the complete session history including all user and assistant messages. This gives the hook's bash script access to all conversation content, which may include sensitive information like API keys, passwords, or confidential business context discussed during the session.
MEDIUM Bash(*) Permission Enables Unconstrained Filesystem Read Without Confirmation -15 ▶
With Bash(*) pre-approved, the discover and explore skills can read any file accessible to the user account — including ~/.env, ~/.ssh/id_rsa, ~/.aws/credentials — as part of their stated codebase exploration mission. The skill's stochastic keyword seeding and mandatory anchor phases explicitly read package.json and entry points throughout the project tree. If manipulated via prompt injection, the agent could read sensitive files and write them to DARWIN artifact files or Serena memory without triggering any user permission dialog.
MEDIUM SessionStart Hook Auto-Creates Filesystem Structure Without Consent -8 ▶
darwin-init.sh is registered as a SessionStart hook that runs automatically at the beginning of every Claude Code session in a project with this plugin installed. It unconditionally creates docs/darwin/_meta/, docs/darwin/templates/, docs/darwin/runs/ directories and initializes run-seq.json and latest-run.json state files. This persistent side-effect runs without any user interaction or consent, and cannot be opted out of without removing the plugin.
MEDIUM Untrusted Codebase Content Pasted Verbatim Into Sub-Agent Dispatch Prompts -12 ▶
The darwin-skeptic and darwin-revise command templates explicitly instruct the agent to paste the full contents of plan.md, critique.md, and explore.md files directly into sub-agent dispatch prompts with no sanitization. These files are read from the user's codebase. A malicious repository could embed adversarial instructions in these files that manipulate the sub-agent's behavior — a secondary prompt injection attack via the project being analyzed.
MEDIUM PreToolUse Hook Can Block Task Tool Dispatch Based on Filesystem State -5 ▶
enforce-spec-gate.sh is registered as a PreToolUse hook for the Task tool and exits with code 1 to block sub-agent dispatch whenever docs/darwin/_meta/checkpoint-spec-skeptic.json exists. While designed for spec validation, this gives the plugin author indirect control over whether the agent can use sub-agents, based entirely on filesystem state that the plugin itself creates and manages.
LOW Session-Lock Pattern Can Prevent User-Controlled Session Exit -20 ▶
The stop hook mechanism constitutes a session-lock pattern: the agent cannot exit until it outputs specific promise strings AND the ledger state matches. In legitimate use this enforces TDD discipline. In a malicious adaptation, always returning {"decision": "block"} or requiring conditions that can never be satisfied would hold users' sessions open indefinitely, consuming API tokens and preventing the user from closing the interaction.
LOW Multi-Agent Orchestration With Broad Permissions Creates Difficult-to-Audit Trust Surface -10 ▶
DARWIN orchestrates four sub-agent types (darwin-worker, darwin-skeptic, darwin-revise, darwin-consolidator) each with broad tool permissions inherited from the parent session's Bash()/Write()/Edit(*) grants. This multi-agent architecture creates a complex trust surface where malicious instructions could be laundered through seemingly-legitimate sub-agent roles, making it difficult to trace the origin of any specific action or file access.
LOW Serena MCP Memory Write-Back Persists Codebase Knowledge Across Sessions -10 ▶
The discover skill's Phase 6 explicitly writes architectural learnings about the user's project to Serena MCP persistent memory after each exploration session. This includes module boundaries, naming conventions, API patterns, known hazards, and integration points. Wherever Serena MCP stores this data, it persists across future Claude Code sessions and potentially across different projects sharing the same Serena instance, creating a mechanism for sensitive architectural information to leak across session boundaries.
LOW .claude/settings.json Permission Bypass Reduces Prompt Injection Defense Depth -7 ▶
The Bash()/Write()/Edit(*) pre-approval in .claude/settings.json eliminates the user confirmation step that would otherwise serve as a break-glass checkpoint if an injected prompt instruction directed the agent to execute harmful commands. With confirmations removed, any successful prompt injection from the codebase or runtime context commands would execute without an additional human-in-the-loop gate.
INFO Sensitive Credential Files Read Before Git Clone — Attributed to Audit Harness -12 ▶
inotify and auditd monitoring detected open/access/close_nowrite events on .env, .ssh/id_rsa, .aws/credentials, .npmrc, .docker/config.json, and .config/gcloud/application_default_credentials.json at epoch 1787685034, approximately 5 seconds before git clone executed at 1787685039. The canary integrity system reports all files intact. The sequential read of all six credential files at identical timestamps is consistent with the audit harness computing canary baseline checksums prior to installation, not with the skill itself. No network exfiltration was observed.
INFO Credential File Reads Detected Pre-Clone — Files Confirmed Intact -18 ▶
The same credential file access events noted in clone_behavior are evaluated here from an integrity perspective. All six credential files were opened and read (CLOSE_NOWRITE, indicating no modification) before git clone occurred. The canary monitoring system reports integrity intact. The timing (5 seconds before clone) and pattern (all files at identical timestamp) strongly suggests audit harness baseline collection rather than malicious reads. No data was exfiltrated to the network during or after these reads.