Back to skill

Security audit

Saturnday

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed wrapper around Saturnday, but users should treat run mode as high-impact because it can modify repositories and send code to a chosen AI backend.

Use Scan mode for read-mostly review work. Use Guard or Run only on repositories you are prepared to let Saturnday modify, commit to, and analyze. Prefer installing `saturnday==1.8.0` in a virtual environment or container, and expose only the API key and repository needed for the chosen backend.

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
SKILL.md:22
Finding

Unpinned Third-Party Package Installation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 22, 45, and 226
Vulnerability Type: Unpinned third-party dependency installation
Risk Level: Medium

Vulnerable Code

At line 22:

yaml
install:
  - cmd: pip install saturnday
  - cmd: echo "Saturnday installed. Run 'saturnday version' to verify."

At lines 43–46:

markdown
If saturnday is not installed, run:
```bash
pip install saturnday
text

At line 226:

```markdown
- `pip install saturnday` (Python 3.10+)

Technical Analysis

The skill instructs users and its installation framework to install saturnday without an exact version constraint, package hash, lock file, or explicitly trusted package index. Consequently, pip resolves whichever version is current on the configured index, along with unconstrained transitive dependencies.

This dependency supplies the saturnday executable invoked by every bundled Python script. Run mode also gives that executable access to target repositories, permits repository modifications, and may connect to AI backends. The reviewed skill discloses those operational effects, but the dependency is not cryptographically bound to the version that was audited.

This is a supply-chain weakness rather than evidence that the current package is malicious. Exploitation requires compromise or substitution of the package, one of its dependencies, or the package index/resolution path.

Attack Path

  1. A user installs the skill or follows its documented pip install saturnday command.
  2. pip queries the configured package index and resolves the latest available saturnday release and its transitive dependencies.
  3. An attacker publishes or substitutes a compromised eligible release, compromises a transitive dependency, or controls an untrusted configured index.
  4. The compromised code executes during package installation or when one of the wrappers invokes the saturnday executable.
  5. The malicious dependency acts with the invoking user ...[truncated 827 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin saturnday to an exact, reviewed version in every installation instruction:

    bash
    python3 -m pip install "saturnday==1.8.0"
    
  2. Generate a requirements or lock file containing hashes for the package and all transitive dependencies, then require hash verification:

    bash
    python3 -m pip install --require-hashes -r requirements.txt
    
  3. Use an explicitly configured trusted package index or an organization-controlled artifact mirror rather than relying on ambient pip configuration.

  4. Verify downloaded artifacts against approved hashes or signatures before installation.

  5. Install and execute the dependency in an isolated virtual environment or container under a non-privileged account.

  6. Expose only the repository and environment variables required for the chosen operation. Avoid passing unrelated credentials into the process.

  7. Apply the same pinned command consistently at SKILL.md lines 22, 45, and 226, and establish a controlled review process for dependency upgrades.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (15)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill advertises commands that read files, access environment variables, and invoke shell commands, but it does not declare any explicit tool scope such as permissions or allowed-tools. That makes the skill's execution boundary ambiguous and increases the risk that a host agent will grant broader access than necessary, especially because the documented Run and Guard modes can modify repositories and may use API keys from the environment.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/guard.py (reported line 20)May include surrounding context.

python
def check_saturnday_installed() -> bool:
    """Verify saturnday is installed and accessible."""
    try:
        result = subprocess.run(
            ["saturnday", "version"],
            capture_output=True,
            text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/run.py (reported line 24)May include surrounding context.

python
def check_saturnday_installed() -> bool:
    """Verify saturnday is installed and accessible."""
    try:
        result = subprocess.run(
            ["saturnday", "version"],
            capture_output=True,
            text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/scan.py (reported line 21)May include surrounding context.

python
def check_saturnday_installed() -> bool:
    """Verify saturnday is installed and accessible."""
    try:
        result = subprocess.run(
            ["saturnday", "version"],
            capture_output=True,
            text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/guard.py (reported line 71)May include surrounding context.

python
if policy_path:
        cmd.extend(["--policy", policy_path])

    result = subprocess.run(
        cmd,
        capture_output=True,
        text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script silently initializes a git repository and creates an empty commit when .git is absent, changing user data and repository state without prior warning or confirmation. In an agent-execution context, implicit writes are more dangerous because users may expect analysis/orchestration only, and automated commit creation can interfere with existing workflows, policy controls, or forensic expectations.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/run.py (reported line 38)May include surrounding context.

python
def ensure_git_repo(project_path: Path) -> None:
    """Initialize git if the project directory is not already a repo."""
    if not (project_path / ".git").exists():
        subprocess.run(
            ["git", "init"],
            cwd=str(project_path),
            capture_output=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/run.py (reported line 44)May include surrounding context.

python
capture_output=True,
            check=True,
        )
        subprocess.run(
            ["git", "commit", "--allow-empty", "-m", "init"],
            cwd=str(project_path),
            capture_output=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/run.py (reported line 61)May include surrounding context.

python
}
    for backend, binary in checks.items():
        try:
            result = subprocess.run(
                ["which", binary],
                capture_output=True,
                text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The planning stage creates directories and invokes an external tool that writes plan.json and potentially other artifacts, but the user is not clearly warned that filesystem modifications will occur. In a governed AI execution skill, this matters more because users may pass arbitrary paths and natural-language briefs, and the tool acts on their workspace automatically.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/run.py (reported line 102)May include surrounding context.

python
"--backend", backend,
    ]

    result = subprocess.run(
        cmd,
        capture_output=True,
        text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/run.py (reported line 152)May include surrounding context.

python
"--backend", backend,
    ]

    result = subprocess.run(
        cmd,
        capture_output=True,
        text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/scan.py (reported line 67)May include surrounding context.

python
"--format", scan_fmt,
    ]

    result = subprocess.run(
        cmd,
        capture_output=True,
        text=True,

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script creates an output directory when none is provided and later relies on report files being written there. While the function docstring mentions an optional output directory, the code does not visibly inform the user at runtime that files/evidence will be created on disk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code file invokes an external command via subprocess.run to execute 'saturnday scan'. Although the module docstring describes scanning, there is no confirmation prompt, print/log statement before execution, or explicit user-facing warning near the operation itself that the script will launch an external process.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.