Back to skill

Security audit

Disinto Factory

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated factory-operations purpose, but it has review-worthy scoping issues around local journal reads and credential-bearing API calls.

Install only in a trusted repository environment. Use least-privilege Forge and Woodpecker tokens, verify FORGE_API and WOODPECKER_SERVER point to trusted HTTPS endpoints, and avoid letting untrusted text choose read-journal.sh arguments until the --date path handling is fixed.

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

Warning
Location
scripts/read-journal.sh:29
Finding

Path Traversal Allows Reading Markdown Files Outside the Journal Directory

Content
View full analysis
Remediation
View remediation
&2 exit 1 fi ``` Additionally: 1. Check that `--date` has a following value before reading `$2`. 2. Canonicalize both the journal directory and requested file using `realpath`. 3. Verify that the canonical file begins with the canonical journal-directory path. 4. Reject path separators, traversal components, and unexpected filename characters. 5. Continue quoting every path passed to filesystem commands. A defense-in-depth containment check could use: ```bash journal_root=$(realpath "$journal_dir") journal_file=$(realpath -m "${journal_dir}/${target_date}.md") case "$journal_file" in "${journal_root}/"*) ;; *) echo "Error: requested file is outside the journal directory" >&2 exit 1 ;; esac ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
.
Finding

Repository and CI Tokens Can Be Sent to Untrusted or Plaintext API Endpoints

Content
View full analysis
/dev/null) || { echo " (failed to fetch pipelines from Woodpecker)" echo "" return } ``` From `scripts/file-issue.sh`: ```bash all_labels=$(curl -sf -H "Authorization: token ${FORGE_TOKEN}" \ -H "Accept: application/json" \ "${FORGE_API}/labels?limit=50" 2>/dev/null) || { echo "Warning: could not fetch labels, creating issue without labels" >&2 all_labels="[]" } ``` ```bash response=$(curl -sf -X POST \ -H "Authorization: token ${FORGE_TOKEN}" \ -H "Content-Type: application/json" \ -d "$payload" \ "${FORGE_API}/issues") || { echo "Error: failed to create issue" >&2 exit 1 } ``` ### Technical Analysis Network access and authenticated API requests are necessary for the declared functionality: the scripts query Forgejo issues, query Woodpecker pipelines, resolve labels, and create issues. No unrelated local data collection or concealed exfiltration was identified. However, `FORGE_API` and `WOODPECKER_SERVER` completely control the destinations receiving the authorization headers. The scripts do not: - Require HTTPS. - Validate the destination hostname against a trusted allowlist. - Reject embedded URL credentials or malformed URL components. - Require an explicit override before using plaintext HTTP. Consequently, a configuration error or attacker-controlled execution enviro ...[truncated 2258 chars]
Remediation
View remediation
&2 exit 1 ;; esac ``` Apply an equivalent check to `WOODPECKER_SERVER`. 2. If plaintext HTTP is required for isolated local development, require an explicit opt-in variable such as `ALLOW_INSECURE_HTTP=true` and display a clear warning. 3. Parse and validate endpoint URLs using a proper URL parser. Reject: - URL user-information components. - Control characters. - Unexpected schemes. - Hosts outside an administrator-defined allowlist. 4. Bind credentials to separately configured trusted hosts rather than accepting an arbitrary URL and a token in the same unrestricted environment. 5. Use narrowly scoped, read-only tokens for status queries. Use a separate token with only issue-creation permissions for `file-issue.sh` where supported. 6. Avoid sharing a broad repository token across read-only and mutating operations. 7. Apply restrictive secret handling at the deployment layer, including protected environment injection, log redaction, token rotation, and short-lived credentials where supported. 8. Document the expected trusted hostnames and fail closed when endpoint validation fails. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
88% confidence
Finding

The description presents a broad operational skill for the autonomous code factory, including active management actions and multiple inspection domains. The code chunk, however, only implements a status-reporting shell script with three functions: checking agent active marker files under PROJECT_REPO_ROOT/state, fetching open issues from a forge API, and fetching recent CI pipelines from Woodpecker. There are no write actions, no issue creation, no journal access, and no dependency graph logic. While parts of the description overlap with the script’s behavior (querying CI pipelines and some factory-status inspection), the declared purpose materially overstates the implemented capabilities, so this is a mismatch.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill exposes powerful execution capability via bash, curl, jq, and git while declaring no explicit tool scope or allowed-tools boundary. In an agent setting, this weakens least-privilege controls and can allow broader command execution than users or orchestrators may expect, especially since the documented workflows include API calls and repository access using environment tokens.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/file-issue.sh (reported line 80)May include surrounding context.

sh
--argjson l "$label_ids" \
    '{title: $t, body: $b, labels: $l}')

response=$(curl -sf -X POST \
    -H "Authorization: token ${FORGE_TOKEN}" \
    -H "Content-Type: application/json" \
    -d "$payload" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/read-journal.sh (reported line 62)May include surrounding context.

sh
echo "Its memory lives in forge issues labeled 'prediction/unreviewed' and 'prediction/actioned'."
        echo ""
        echo "Query predictions with:"
        echo "  curl -sH 'Authorization: token \${FORGE_TOKEN}' '\${FORGE_API}/issues?state=open&labels=prediction%2Funreviewed'"
        exit 0
        ;;
    *)

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

This shell script is a code file, so SQP-2 applies to sensitive credential handling. The printed example explicitly uses FORGE_TOKEN in an Authorization header, but there is no accompanying warning or explanatory comment about using or protecting that credential.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.