Back to skill

Security audit

Nous Safety

Security checks for vulnerabilities and agentic risk

Overview

The skill’s safety purpose is coherent, but its installer runs mutable remote GitHub code and can delete a caller-selected installation directory during update failure.

Review the installer before running it. Prefer installing from a pinned commit or signed release in a virtual environment, avoid sudo/root, and do not set NOUS_INSTALL_DIR to any directory containing unrelated data.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/install.sh:24
Finding

Unpinned Remote Repository Is Retrieved and Executed During Installation

Content
View full analysis

Vulnerability Details

File Location: scripts/install.sh, lines 7 and 24-46
Vulnerability Type: Remote payload retrieval and execution
Risk Level: High

Vulnerable Code

bash
REPO="https://github.com/dario-github/nous.git"
bash
# Clone or update
if [ -d "$INSTALL_DIR" ]; then
    echo "📦 Updating existing installation..."
    cd "$INSTALL_DIR"
    git pull --ff-only 2>/dev/null || {
        echo "⚠️  git pull failed, doing fresh clone..."
        cd /tmp
        rm -rf "$INSTALL_DIR"
        git clone "$REPO" "$INSTALL_DIR"
        cd "$INSTALL_DIR"
    }
else
    echo "📦 Cloning from GitHub..."
    git clone "$REPO" "$INSTALL_DIR"
    cd "$INSTALL_DIR"
fi

# Install with cozo support (recommended for knowledge graph)
echo "📦 Installing Python package..."
pip install -e ".[cozo]" 2>/dev/null || {
    echo "⚠️  cozo-embedded install failed (expected on some platforms)"
    echo "📦 Installing without KG support..."
    pip install -e .
}

Technical Analysis

The installer retrieves the current state of a remote Git repository without pinning an immutable commit, release artifact, checksum, or cryptographic signature. It subsequently passes that downloaded repository to pip install -e, which can execute package build hooks and install mutable transitive dependencies.

The effective payload is therefore not limited to the code reviewed in this skill package. Changes made to the upstream default branch after this audit will automatically become part of future installations. A compromise of the upstream repository, maintainer account, dependency publication process, or an unpinned transitive dependency could introduce arbitrary executable code.

Although the repository URL matches the homepage declared in SKILL.md, that correspondence does not provide integrity protection or ensure that future repository contents remain trustworthy.

Attack Path

...[truncated 1320 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin the installation to a specific, reviewed commit hash or immutable signed release instead of the mutable default branch.
  2. Download a versioned release artifact and verify a published SHA-256 or stronger digest before extracting or executing it.
  3. Require cryptographic release signatures and verify them against a maintainer key distributed through a separate trusted channel.
  4. Use a dependency lockfile containing exact versions and hashes for all direct and transitive Python dependencies.
  5. Invoke Python package installation through the validated interpreter, such as python3 -m pip, and install into a dedicated virtual environment.
  6. Avoid installing optional dependency groups by default. Require explicit user consent for components such as cozo.
  7. Perform installation with a non-privileged account and document that the script must not be run with sudo or as root.
  8. Add CI controls that reproduce and verify release artifacts from reviewed source before publishing an approved version.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/install.sh:24
Finding

Caller-Controlled Installation Path Can Be Recursively Deleted

Content
View full analysis

Vulnerability Details

File Location: scripts/install.sh, lines 8 and 24-32
Vulnerability Type: Unsafe recursive deletion using an unvalidated environment-controlled path
Risk Level: Medium

Vulnerable Code

bash
INSTALL_DIR="${NOUS_INSTALL_DIR:-$HOME/.nous}"
bash
if [ -d "$INSTALL_DIR" ]; then
    echo "📦 Updating existing installation..."
    cd "$INSTALL_DIR"
    git pull --ff-only 2>/dev/null || {
        echo "⚠️  git pull failed, doing fresh clone..."
        cd /tmp
        rm -rf "$INSTALL_DIR"
        git clone "$REPO" "$INSTALL_DIR"
        cd "$INSTALL_DIR"
    }

Technical Analysis

INSTALL_DIR can be supplied through the NOUS_INSTALL_DIR environment variable. The script checks only whether the supplied value names an existing directory. It does not canonicalize the path, confirm that it is a dedicated Nous installation, or reject dangerous targets such as the user's home directory or another unrelated data directory.

If git pull --ff-only fails for any reason, the error handler passes the caller-controlled path directly to rm -rf. Quoting prevents shell word splitting and command substitution at this point, but it does not prevent deletion of a valid yet unsafe directory selected by the caller.

The update can fail because the target is not a Git repository, has no valid upstream, contains divergent history, has corrupted Git metadata, or experiences a network or authentication error. Consequently, the destructive branch can be reached without unusual conditions.

Attack Path

  1. A user, wrapper script, compromised environment file, or attacker with influence over process environment variables sets NOUS_INSTALL_DIR to an existing directory containing unrelated data.
  2. The user invokes scripts/install.sh.
  3. The [ -d "$INSTALL_DIR" ] test succeeds.
  4. The script changes into the selected directory and runs git pull --ff-only.
  5. The ...[truncated 864 chars]
Remediation
View remediation

Remediation Suggestions

  1. Canonicalize the requested path before using it and reject empty paths, /, $HOME, /home, /usr, /etc, /var, /tmp, and other sensitive or broad locations.
  2. Restrict installation to a dedicated application directory or an explicitly approved parent directory.
  3. Before modifying an existing directory, verify that it is a Nous checkout by checking its canonical Git remote URL and a dedicated installation marker.
  4. Never delete an existing directory automatically merely because an update failed.
  5. Replace destructive deletion with an atomic rename to a timestamped backup directory, and provide a separate explicit cleanup operation.
  6. If deletion remains necessary, require interactive confirmation and display the canonical path that will be removed.
  7. Treat network and Git update failures as non-destructive errors: abort installation and preserve the existing installation.
  8. Refuse to run the installer as root unless system-wide installation is intentionally supported and protected by additional path validation.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep

Static analysis

No suspicious patterns detected.