Back to skill

Security audit

God's eye view of your dev repos. Multi-project tracking across GitHub/Azure DevOps. AI learns from your commits to upgrade your agents.md.

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent project-dashboard purpose, but it reads and stores repository and agent-instruction content with weak scoping and hardening.

Install only after reviewing the code and using it on repositories you trust. Keep ~/.god-mode private, avoid custom analysis.agentFiles entries with absolute paths or .. components, do not automatically send generated prompts to an LLM with write-capable tools, and prefer a non-persistent PATH setup unless you trust the cloned scripts directory.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (5)

T01 · Skill Instruction Hijacking

Error
Location
scripts/commands/agents.sh:129
Finding
Indirect Prompt Injection Through Repository-Controlled Content<![CDATA[ ## Vulnerability Details **File Location**: `scripts/commands/agents.sh:129-168`; `prompts/agent-analysis.md:12-35, 88-92` **Vulnerability Type**: Indirect prompt injection **Risk Level**: High ### Vulnerable Code ```bash # Get sample commit messages local commit_samples=$(db_query "SELECT message FROM commits WHERE project_id = '$project_id' ORDER BY timestamp DESC LIMIT 10" | jq -r '.[].message | split("\n")[0]' | head -10) # Build the complete prompt local prompt="$prompt_template" prompt="${prompt//\{\{ project_name \}\}/$project_name}" prompt="${prompt//\{\{ repository \}\}/$repo}" prompt="${prompt//\{\{ days \}\}/$analysis_days}" prompt="${prompt//\{\{ commit_count \}\}/$commit_count}" prompt="${prompt//\{\{ agent_content \}\}/$agent_content}" prompt="${prompt//\{\{ commit_types \}\}/$commit_types_formatted}" prompt="${prompt//\{\{ file_patterns \}\}/$topics_formatted}" prompt="${prompt//\{\{ revert_count \}\}/$(echo "$patterns" | jq '.churn.count')}" prompt="${prompt//\{\{ typo_fix_count \}\}/$(echo "$patterns" | jq '.churn.count')}" prompt="${prompt//\{\{ repeated_patterns \}\}/See topics above}" prompt="${prompt//\{\{ commit_samples \}\}/$commit_samples}" # Output the prompt for the LLM echo "" echo "$prompt" ``` The corresponding prompt template inserts the content directly into an instruction-bearing Markdown document: ```markdown ## Current Agent Instructions ```markdown {{ agent_content }} ``` ### Commit Message Samples {{ commit_samples }} ## Your Task Analyze the agent instructions against the commit patterns and identify: ``` ### Technical Analysis Agent instruction files and commit messages are controlled by repository contributors. They are inserted directly into a prompt that is intended to be sent to an LLM. The template does not establish a trust boundary or tell the LLM that embedded directives must be treated exclusive ...[truncated 1489 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat agent files, commit messages, project names, and repository metadata as untrusted data. 2. Put untrusted values in a structured data message separate from the controlling instructions. 3. Add explicit instructions that the model must not follow commands found in repository content. 4. Encode or escape Markdown fence delimiters before interpolation. 5. Prefer a JSON request structure with separately named fields over free-form string substitution. 6. Validate the LLM response against a strict JSON schema and reject additional fields or non-JSON text. 7. Require explicit human approval before applying generated recommendations. 8. Limit downstream tools available during this analysis to read-only operations. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/lib/db.sh:23
Finding
SQL Injection Through Raw SQLite String Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/lib/db.sh:23-30, 43-49, 58-72, 80-104, 113-176`; `scripts/commands/sync.sh:165-204`; `scripts/commands/projects.sh:203-208`; `scripts/lib/analysis/patterns.sh:14-217`; `scripts/commands/agents.sh:146-149` **Vulnerability Type**: SQL injection **Risk Level**: High ### Vulnerable Code The database helpers execute complete SQL strings without parameter binding: ```bash # Run a query and return results as JSON db_query() { local sql="$1" sqlite3 -json "$DB_PATH" "$sql" 2>/dev/null || echo "[]" } # Run a query that doesn't return data db_exec() { local sql="$1" sqlite3 "$DB_PATH" "$sql" } ``` Multiple unescaped values are then interpolated into those strings: ```bash db_upsert_commits() { local project_id="$1" local commits commits=$(cat) echo "$commits" | jq -c '.[]' | while read -r commit; do local sha=$(echo "$commit" | jq -r '.sha') local author=$(echo "$commit" | jq -r '.author // .commit.author.name') local message=$(echo "$commit" | jq -r '.message // .commit.message' | head -1 | sed "s/'/''/g") local timestamp=$(echo "$commit" | jq -r '.date // .commit.author.date') if [[ "$timestamp" =~ ^[0-9]{4}- ]]; then timestamp=$(date -d "$timestamp" +%s 2>/dev/null || echo "0") fi db_exec "INSERT OR REPLACE INTO commits (sha, project_id, author, message, timestamp) VALUES ('$sha', '$project_id', '$author', '$message', $timestamp);" done } ``` PR and issue records contain additional raw fields: ```bash db_exec "INSERT OR REPLACE INTO pull_requests (id, project_id, number, title, state, author, created_at, updated_at, labels) VALUES ('${PROJECT_ID}:pr:${PR_NUM}', '$PROJECT_ID', $PR_NUM, '$PR_TITLE', '$PR_STATE', '$PR_AUTHOR', '$PR_CREATED', '$PR_UPDATED', '$PR_LABELS');" db_exec "INSERT OR REPLACE INTO issues (id, project_id, number, ...[truncated 2719 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace shell-built SQL with a language binding that supports prepared statements and bound parameters. 2. If the SQLite CLI must be retained, use a rigorously tested parameter-binding mechanism rather than manual interpolation. 3. Do not rely on selective apostrophe replacement; every data value must be bound separately. 4. Validate numeric values such as timestamps and issue numbers before use. 5. Allowlist the `sync_state` column name instead of accepting an arbitrary field identifier. 6. Restrict project IDs to provider-specific formats and reject quotes, control characters, and unexpected path components. 7. Use transactions for batch imports and fail closed when a statement is invalid. 8. Add regression tests using apostrophes, semicolons, SQL comments, newlines, and Unicode control characters in every remote and local field. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/lib/analysis/agents.sh:28
Finding
Repository-Boundary Bypass in Configurable Agent-File Discovery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/lib/analysis/agents.sh:28-53, 100-127, 231-251` **Vulnerability Type**: Path traversal and unauthorized local-file access **Risk Level**: Medium ### Vulnerable Code ```bash find_agent_file() { local repo_path="$1" repo_path="${repo_path/#\~/$HOME}" if [[ ! -d "$repo_path" ]]; then return 1 fi local patterns if config_exists; then mapfile -t patterns < <(config_get_agent_files) else patterns=("${DEFAULT_AGENT_FILES[@]}") fi for pattern in "${patterns[@]}"; do local file_path="$repo_path/$pattern" if [[ -f "$file_path" ]]; then echo "$file_path" return 0 fi done return 1 } ``` The returned path is read and included in the analysis data: ```bash if [[ -n "$local_path" ]]; then local_path="${local_path/#\~/$HOME}" local agent_file agent_file=$(find_agent_file "$local_path") if [[ -n "$agent_file" ]]; then local content content=$(cat "$agent_file") local rel_path="${agent_file#$local_path/}" jq -n --arg path "$rel_path" --arg content "$content" --arg source "local" \ '{path: $path, content: $content, source: $source}' return 0 fi fi ``` The content is subsequently persisted: ```bash db_exec "INSERT INTO agent_files (project_id, path, content_hash, content, captured_at) VALUES ('$project_id', '$path', '$hash', '$escaped_content', $now) ON CONFLICT(project_id, path) DO UPDATE SET content_hash = '$hash', content = '$escaped_content', captured_at = $now;" ``` ### Technical Analysis Configured agent-file patterns are concatenated with the repository path without canonicalization or containment validation. A pattern containing `../` can resolve outside the repository. Symlinks can create a similar boundary bypass because the code verifies only that the r ...[truncated 1381 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Canonicalize both the repository root and candidate path with `realpath`. 2. Require every canonical candidate path to begin with the canonical repository root followed by a path separator. 3. Reject absolute patterns, `..` components, empty components, NUL bytes, and control characters. 4. Reject symlinks or verify the canonical symlink target remains inside the repository. 5. Restrict configured patterns to a documented allowlist of repository-relative filenames. 6. Do not persist file contents unless necessary; a content hash may be sufficient for cache invalidation. 7. Display the resolved path and request confirmation before analyzing a non-default file. 8. Apply output redaction and size limits before generating LLM-bound data. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/lib/config.sh:195
Finding
Unsafe yq Expression Construction From Project Metadata<![CDATA[ ## Vulnerability Details **File Location**: `scripts/lib/config.sh:195-221, 224-246` **Vulnerability Type**: Expression injection and configuration corruption **Risk Level**: Medium ### Vulnerable Code ```bash config_add_project() { local id="$1" local name="${2:-}" local priority="${3:-medium}" if ! config_exists; then config_init fi if ! _has_yq; then echo "Error: yq is required to modify config" >&2 echo "Install with: brew install yq (macOS) or apt install yq (Debian/Ubuntu)" >&2 return 1 fi local existing existing=$(config_get_project "$id") if [[ -n "$existing" && "$existing" != "null" ]]; then echo "Project already exists: $id" >&2 return 1 fi local new_project="{\"id\": \"$id\"" [[ -n "$name" ]] && new_project="$new_project, \"name\": \"$name\"" new_project="$new_project, \"priority\": \"$priority\"}" yq -i ".projects += [$new_project]" "$GOD_MODE_CONFIG" echo "Added project: $id" } ``` Removal has the same issue: ```bash config_remove_project() { local search="$1" if ! _has_yq; then echo "Error: yq is required to modify config" >&2 return 1 fi local project project=$(config_get_project "$search") if [[ -z "$project" || "$project" == "null" ]]; then echo "Project not found: $search" >&2 return 1 fi local id id=$(echo "$project" | jq -r '.id') yq -i "del(.projects[] | select(.id == \"$id\"))" "$GOD_MODE_CONFIG" echo "Removed project: $id" } ``` ### Technical Analysis Project IDs, names, and priorities are embedded into a manually constructed JSON fragment, which is then embedded in a `yq` expression. The values are not encoded with a JSON serializer and are not passed to `yq` as isolated variables. Quotes, backslashes, braces, or expression syntax in a value can break out of the intended string context. This permits malformed expressions and m ...[truncated 1203 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Never construct JSON or `yq` expressions through string concatenation. 2. Generate the project object with `jq -n --arg id "$id" --arg name "$name" --arg priority "$priority"`. 3. Pass structured data into `yq` through a supported variable or input-file mechanism. 4. Pass deletion IDs through environment variables and reference them as data rather than embedding them in expressions. 5. Validate provider-specific project identifiers and constrain priority to `high`, `medium`, or `low`. 6. Write configuration updates to a temporary file with restrictive permissions, validate the result, and atomically replace the original file. 7. Add tests covering quotes, backslashes, braces, newlines, and expression operators. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/lib/db.sh:4
Finding
Plaintext Sensitive Cache Created Without Explicit Permission Hardening<![CDATA[ ## Vulnerability Details **File Location**: `scripts/lib/db.sh:4-15`; `scripts/setup.sh:79-97`; `sql/schema.sql:25-103` **Vulnerability Type**: Insecure storage permissions **Risk Level**: Medium ### Vulnerable Code ```bash GOD_MODE_HOME="${GOD_MODE_HOME:-$HOME/.god-mode}" DB_PATH="$GOD_MODE_HOME/cache.db" SCHEMA_PATH="$(dirname "${BASH_SOURCE[0]}")/../../sql/schema.sql" db_init() { mkdir -p "$GOD_MODE_HOME" if [[ ! -f "$DB_PATH" ]]; then sqlite3 "$DB_PATH" < "$SCHEMA_PATH" echo "Database initialized at $DB_PATH" fi } ``` Setup likewise creates the directory without an explicit mode: ```bash # Data directory echo -n " Data directory (~/.god-mode): " if [[ -d "$HOME/.god-mode" ]]; then success "exists" else mkdir -p "$HOME/.god-mode" success "created" fi ``` The database stores full repository and instruction content: ```sql CREATE TABLE IF NOT EXISTS commits ( sha TEXT PRIMARY KEY, project_id TEXT NOT NULL, author TEXT, author_email TEXT, message TEXT, timestamp INTEGER ); CREATE TABLE IF NOT EXISTS agent_files ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_id TEXT NOT NULL, path TEXT NOT NULL, content_hash TEXT, content TEXT, captured_at INTEGER ); ``` ### Technical Analysis The cache contains potentially confidential information from private repositories, including commit authors, messages, project paths, issue and pull-request metadata, and complete agent instruction files. The code does not set `umask 077`, request mode `0700` for the cache directory, or enforce mode `0600` for the database. Resulting permissions depend on the caller's environment. Under a permissive umask, the directory and database can be readable by other local accounts. Existing directories or files with unsafe permissions are also accepted without remediation. ### Attack Path 1. The victim runs `god setup`, `god sync`, or another command that invokes `db_init`. 2. The cach ...[truncated 719 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set `umask 077` before creating configuration or cache files. 2. Create the data directory with `mkdir -p -m 700 "$GOD_MODE_HOME"`. 3. Enforce `chmod 700 "$GOD_MODE_HOME"` and `chmod 600 "$DB_PATH"` after creation. 4. Verify that neither the directory nor database is an unsafe symlink before use. 5. Minimize stored data; avoid retaining complete instruction contents when a cryptographic hash is sufficient. 6. Provide configurable retention limits and a command to securely clear cached project data. 7. Clearly disclose that LLM-bound prompts may contain repository content even though the local cache itself does not transmit data. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (22)

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Content
Testing
- Unit tests for all new functions
- Run `npm test` before commits
```

## Installation

### Prerequisites

- `gh` - [GitHub CLI](https://cli.github.com/) (authenticated)
- `sqlite3` - Usually pre-installed
- `jq` - `brew install jq` or `apt install jq`

### Install

```bash
# Clone
git clone https://github.com/InfantLab/god-mode-skill
cd god-mode-skill

# Add to PATH
echo 'export PATH="$PATH:'$(pwd)'/scripts"' >> ~/.bashrc
source ~/.bashrc

# Setup
god setup
```

Or for OpenClaw:
```bash
openclaw skills add god-mode
```

## Quick Start

```bash
# 1. Add your first project
god projects add github:yourname/yourrepo

# 2. Sync data
god sync

# 3. See the overview
god status

# 4. Analyze your agents.md
god agents analyze yourrepo
```

## Commands

| Command | Description |
|---------|-------------|
| `god status` | Overview of all projects |
| `god status <project>` | Details for one project |
| `god sync` | Fetch latest data
Confidence
75% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill includes a first-run setup workflow that creates directories, initializes config/database state, checks dependencies/authentication, and may add repositories and trigger syncs, but the top-level description does not emphasize this bootstrap and mutation role. Users expecting passive oversight may unknowingly authorize filesystem changes and external sync activity, which raises both integrity and privacy concerns.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill includes a first-run setup workflow that creates directories, initializes config/database state, checks dependencies/authentication, and may add repositories and trigger syncs, but the top-level description does not emphasize this bootstrap and mutation role. Users expecting passive oversight may unknowingly authorize filesystem changes and external sync activity, which raises both integrity and privacy concerns.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
The skill includes a first-run setup workflow that creates directories, initializes config/database state, checks dependencies/authentication, and may add repositories and trigger syncs, but the top-level description does not emphasize this bootstrap and mutation role. Users expecting passive oversight may unknowingly authorize filesystem changes and external sync activity, which raises both integrity and privacy concerns.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill includes a first-run setup workflow that creates directories, initializes config/database state, checks dependencies/authentication, and may add repositories and trigger syncs, but the top-level description does not emphasize this bootstrap and mutation role. Users expecting passive oversight may unknowingly authorize filesystem changes and external sync activity, which raises both integrity and privacy concerns.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill includes a first-run setup workflow that creates directories, initializes config/database state, checks dependencies/authentication, and may add repositories and trigger syncs, but the top-level description does not emphasize this bootstrap and mutation role. Users expecting passive oversight may unknowingly authorize filesystem changes and external sync activity, which raises both integrity and privacy concerns.

Session Persistence

Medium
Category
Rogue Agent
Content
Testing (not mentioned)
  But 31% of your commits touch tests
  → Add: "Write tests for new code"

📝 SUGGESTED ADDITIONS
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
4. **Suggests improvements** based on your patterns

Example insights:
- "You write lots of tests but don't mention testing in agents.md"
- "40% of commits are error-handling fixes - add error handling guidance"
- "Your 'use TypeScript strict' instruction is working - 0 type errors"
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill advertises commands that sync data from GitHub and other providers, which implies network access, but it does not declare an explicit tool scope such as permissions or allowed-tools. This weakens user visibility and policy enforcement around outbound access, increasing the chance that an agent invokes network-capable behavior without clear authorization boundaries.

Session Persistence

Medium
Category
Rogue Agent
Content
## Overview

**god-mode** gives you a bird's-eye view of all your coding projects and coaches you to write better AI agent instructions.

**Key features:**
- Multi-project status dashboard
Confidence
76% confidence
Finding
The skill stores project data and analyses locally in ~/.god-mode, including commits, PRs, issues, and saved contexts, which creates persistent retention of potentially sensitive repository metadata. While persistence is part of the advertised design, it still expands the exposure window if the local machine is shared, compromised, or subject to over-collection beyond what users expect.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script assembles repository metadata, full agent instruction content, commit summaries, and recent commit messages into a prompt and prints it for downstream LLM handling. That can expose sensitive internal codebase context, secrets accidentally present in agents.md or commit messages, and private repository identifiers to an external model or logs without any consent, warning, redaction, or policy gate.

Intent-Code Divergence

Medium
Confidence
88% confidence
Finding
The usage/help text frames the command as only listing and managing configured projects. In practice, adding a project also initializes and upserts into the database, and removing a project can delete commits, pull requests, issues, sync state, analyses, and project rows, which is materially broader than the documented behavior.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The file header and help text describe this script as `god status` that shows an overview or project details, but the script calls `show_project_detail`/`show_overview` at L67-L70 before those functions are defined later in the file. In bash scripts, this means the documented behavior is contradicted by the actual execution flow, which will fail rather than provide status output.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This code stores full agent file contents in the database, not just a hash or metadata, which can persist sensitive instructions, secrets, internal URLs, or prompt-injection content longer than necessary. In the god-mode context, which aggregates cross-repo project status and agent guidance, central retention increases blast radius if the database is later queried by broader tooling or exposed to unauthorized users.

Session Persistence

Medium
Category
Rogue Agent
Content
echo ""

# Step 2: Create directories
echo -e "${BOLD}Setting up directories...${RESET}"
echo ""
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Low
Confidence
95% confidence
Finding
The install instructions append a new PATH entry to ~/.bashrc and immediately source it, which creates a persistent shell-environment change without warning the user. While common in setup guides, persistent profile modification can unexpectedly affect later sessions, command resolution, and troubleshooting, especially if users do not realize a repo-local scripts directory has been permanently trusted.

Intent-Code Divergence

Low
Confidence
85% confidence
Finding
The script first initializes the database and immediately dispatches to a status view at L56-L71, then repeats a second 'Run the appropriate view' dispatch at L305-L315. This contradicts the implied intent of a single status command execution and indicates the code structure does not match the documented command behavior.

Missing User Warnings

Low
Confidence
84% confidence
Finding
This code calls the GitHub API to retrieve repository file contents and then returns the decoded content, but there is no confirmation prompt or user-facing disclosure at the point of network access. Because the operation transmits repository identifiers to an external service and reads remote content, it fits the code-file warning criterion.

Missing User Warnings

Low
Confidence
74% confidence
Finding
The function reads the discovered local agent file with `cat` and packages its full contents into JSON, but there is no confirmation prompt, print/log message, or explicit warning near this data-access behavior. Reading and surfacing local instruction files may affect user privacy expectations, so the behavior should be disclosed.

Missing User Warnings

Low
Confidence
76% confidence
Finding
This code file performs data access and analysis over commit messages and later author metadata, which may contain sensitive project or personal information. Although the file has developer-facing comments about its purpose, it lacks any user-facing prompt, log, or warning indicating that repository history content will be queried and processed.

Missing User Warnings

Low
Confidence
85% confidence
Finding
The code initializes and writes to a SQLite database at a user-home path, creating directories and a database file if needed. Although the file contains developer comments and one echo during initialization, there is no consistent user disclosure for ongoing write operations such as inserts and updates performed throughout this library.

Intent-Code Divergence

Low
Confidence
95% confidence
Finding
At L60, the comment says Azure and GitLab are "Stubbed, not fully implemented," and provider_supported returns failure for them. But provider_call at L38-L47 actively dispatches Azure and GitLab function names as if those providers are available. This creates an intent/documentation contradiction about which providers the interface actually supports.

Static analysis

No suspicious patterns detected.