Back to skill

Security audit

Jits Builder

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent mini-app-building purpose, but its bundled shell script and install guidance create real review-worthy risks around public exposure, unsafe arguments, and unpinned executable downloads.

Review before installing. Do not use this skill with secrets, private data, authentication flows, or anything that should stay local unless it is changed to require explicit tunnel opt-in, validate app names and ports, avoid node -e interpolation, remove wildcard cleanup, verify PID ownership, and pin or verify any remotely downloaded executable files.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
jits.sh:45
Finding

Arbitrary JavaScript Execution Through Unsanitized Port and App Name Arguments

Content
View full analysis
{ res.writeHead(200, {'Content-Type': 'text/html'}); res.end(html); }).listen($port, () => console.log('JITS server on port $port')); " & echo $! > "$JITS_DIR/$name.pid" echo "$port" > "$JITS_DIR/$name.port" echo "✅ Serving $name on port $port" ``` ### Technical Analysis The `name` and `port` command-line arguments are inserted directly into JavaScript source passed to `node -e`. They are neither syntactically encoded nor constrained to safe values. The `port` value is particularly exploitable because it is inserted as raw JavaScript inside the argument list of `listen()`: ```javascript .listen($port, () => ...) ``` An attacker able to invoke the script can supply JavaScript syntax instead of a numeric port, terminate the intended expression, and append arbitrary Node.js statements. Node.js exposes filesystem, process, and child-process APIs, so injected code can execute operating-system commands with the privileges of the account running the Skill. The `name` argument is also embedded inside a single-quoted JavaScript string in `fs.readFileSync()`. A crafted value containing quote characters and JavaScript syntax could escape that string if the corresponding path-validation precondition can be satisfied. ### Attack Path 1. The attacker gains the ability to invoke `jits.sh serve`, direc ...[truncated 1336 chars]
Remediation
View remediation
65535) { throw new Error("Invalid port"); } const html = fs.readFileSync(htmlFile, "utf8"); http.createServer((req, res) => { res.writeHead(200, {"Content-Type": "text/html"}); res.end(html); }).listen(port); ' ``` 3. Restrict app names to a conservative allowlist, such as `^[A-Za-z0-9_-]+$`. 4. Require the port to contain digits only and enforce the range `1` through `65535`. 5. Prefer a separate static Node.js server file instead of dynamically generated `node -e` source. 6. Add negative tests covering quotes, semicolons, parentheses, newlines, path separators, and JavaScript comment syntax. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
jits.sh:25
Finding

Path Traversal Enables Unauthorized Process Termination and File Deletion

Content
View full analysis
/dev/null # Also kill tunnel if exists tunnel_pid=$(cat "$JITS_DIR/$name.tunnel.pid" 2>/dev/null) [ -n "$tunnel_pid" ] && kill "$tunnel_pid" 2>/dev/null rm -f "$JITS_DIR/$name".* echo "🛑 Stopped $name" else echo "❌ App '$name' not found" fi ``` ### Technical Analysis The `name` argument is used as part of filesystem paths without validation or canonicalization. Path components such as `../` can therefore cause the resolved path to leave `/data/clawd/jits-apps`. The script trusts the contents of the resolved `.pid` and `.tunnel.pid` files and passes those values to `kill`. It does not verify that the recorded process belongs to the requested JITS application or that the process command matches the expected Node.js server or Cloudflared tunnel. The cleanup statement is additionally dangerous: ```bash rm -f "$JITS_DIR/$name".* ``` Although the path prefix is quoted, the trailing `.*` is subject to shell glob expansion. With a traversal-containing name, this can delete multiple files outside `JITS_DIR` that share the selected basename. ### Attack Path 1. An attacker identifies or creates a readable PID file outside `JITS_DIR` that is reachable through a relative traversal path and contains the PID of a process owned by the Skill account. 2. The attacker invokes `jits.sh stop` with a name containing traversal components, such as a value conceptually equivalent to `../target`. 3. The expression `$JITS_DIR/$name.pid` resolves outside the intended application directory. 4. The script reads the external PID file and sends `SIGTERM` to the referenced process. 5. It optionally reads a simila ...[truncated 996 chars]
Remediation
View remediation
&2 exit 1 ;; esac ``` 2. Reject all path separators, traversal components, control characters, and leading-dot names. 3. Resolve paths canonically and verify that every resulting path remains under the canonical `JITS_DIR`. 4. Replace wildcard deletion with an explicit list of expected files: ```bash rm -f -- \ "$JITS_DIR/$name.pid" \ "$JITS_DIR/$name.port" \ "$JITS_DIR/$name.url" \ "$JITS_DIR/$name.tunnel.pid" ``` 5. Validate PID-file contents with a digits-only check before calling `kill`. 6. Verify process ownership and command identity through `/proc/$pid/cmdline` or an equivalent platform mechanism before terminating it. 7. Create state files with restrictive permissions and avoid following symbolic links. A dedicated per-app directory with secure ownership and permissions would further reduce exposure. 8. Apply the same app-name validation to the `serve` and `tunnel` operations. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
README.md:43
Finding

Mutable Remote Shell Script Is Downloaded and Marked Executable Without Integrity Verification

Content
View full analysis
Remediation
View remediation
/jits.sh" printf '%s %s\n' '' 'jits.sh' | sha256sum -c - chmod 0755 jits.sh ``` 4. Prefer signed release artifacts and verify the signature against a documented, independently distributed public key. 5. Use `curl -fL` so HTTP errors fail installation rather than being saved as local files. 6. Document the exact version and digest being installed. 7. Ensure automated Skill installers apply equivalent integrity and provenance checks. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (12)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The README advertises that generated tools are deployed 'in seconds via Cloudflare tunnel' and gives a public trycloudflare URL example, but it does not clearly warn users that the result is internet-accessible. This omission is dangerous because users may assume a local-only prototype while unintentionally exposing generated apps, test data, or insecure code to the public internet.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The description says the app is made "instantly accessible" and a Cloudflare tunnel is created, but it does not clearly warn that this exposes the generated app on a public internet-reachable URL. Because users may generate tools containing pasted data or sensitive content, lack of explicit disclosure can lead to unintentional public exposure.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

The stop command uses unsanitized user-controlled input in file paths and then executes rm -f "$JITS_DIR/$name".*, allowing path traversal such as ../ to target files outside the intended directory. Because the same tainted name is also used to read a PID and pass it to kill, an attacker may cause deletion of arbitrary matching files under writable parent paths and potentially signal unintended processes if crafted files exist.

Content

Scanner excerpt · jits.sh (reported line 35)May include surrounding context.

sh
# Also kill tunnel if exists
      tunnel_pid=$(cat "$JITS_DIR/$name.tunnel.pid" 2>/dev/null)
      [ -n "$tunnel_pid" ] && kill "$tunnel_pid" 2>/dev/null
      rm -f "$JITS_DIR/$name".*
      echo "🛑 Stopped $name"
    else
      echo "❌ App '$name' not found"

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · README.md (reported line 51)May include surrounding context.

Manual:

bash
mkdir -p ~/.moltbot/skills/jits-builder
cd ~/.moltbot/skills/jits-builder
curl -O https://raw.githubusercontent.com/Cluka-399/jits-builder/main/SKILL.md
curl -O https://raw.githubusercontent.com/Cluka-399/jits-builder/main/jits.sh

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README presents broad natural-language prompts like 'Build me a timer' or 'Make a page...' without any stated limits on what kinds of apps may be generated. In a skill that turns freeform user requests into executable code and deploys it publicly, this can encourage unsafe use and increase the chance the agent generates software with risky capabilities or mishandles sensitive input.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill encourages activation from broad, everyday phrases like "Build me a pomodoro timer" or "I need a quick tool to convert CSV to JSON," which can overlap with normal conversation and increase the chance of unintended invocation. In this skill, accidental triggering is more dangerous because invocation leads to code generation, local file writes, process startup, and public exposure via a Cloudflare tunnel.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill documents saving generated applications to /data/clawd/jits-apps/<name>.html and managing associated process files, but it does not clearly warn users that content is written persistently to local storage. This can leave sensitive prompts, generated code, or embedded data on disk longer than the user expects, especially when combined with easy natural-language triggering.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script includes built-in public tunneling via cloudflared, which can expose a locally served application to the internet without any authentication, access control, or documented security boundary. In an agent skill context, this is more dangerous because generated or temporary apps may contain sensitive data or unsafe functionality, and the tunnel makes them reachable by anyone with the URL.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The tunnel command publishes a localhost service externally and automatically captures a public trycloudflare URL, but provides no user prompt, warning, or confirmation before exposure. In this skill context, that significantly increases risk because users may assume a local-only preview while the script silently makes the app publicly accessible.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The package description advertises highly capable behavior ('build instant mini-apps' and 'deployed in seconds via Cloudflare tunnel') from vague voice or text input without stating scope limits, approval gates, or safety constraints. In an agent-skill ecosystem, this kind of broad invocation language can encourage unsafe autonomous code generation and exposure of generated apps to the internet, increasing the chance of misuse or accidental deployment of insecure artifacts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The provided HTML template fixes the generated app language to ''. This is a natural-language locale constraint in a universally described skill, and the file does not offer user opt-in or explain why English is required.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
74% confidence
Finding

The comment says 'Internal: serve an HTML file', which suggests a narrow local file-serving action, but the code actually launches a persistent Node.js HTTP server bound to a port. This is a meaningful intent difference because it opens a network service rather than merely returning or printing file contents.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.