Back to skill

Security audit

Jobautopilot Submitter

Security checks for vulnerabilities and agentic risk

Overview

This skill is broadly aligned with job-application automation, but it under-discloses sensitive browser data exposure and uses unsafe temporary shell-script execution for state-changing actions.

Review carefully before installing. This skill may submit real job applications, upload local documents, use an existing browser session, and expose populated form values to the agent context. Prefer a version that removes returned field values, excludes credential/payment/security fields, uses mktemp-style private temporary files with unconditional cleanup, pins dependencies, and clearly documents resume-file data access.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/check_required_fields.js:103
Finding

Required Form Values Are Disclosed to the Agent and Command Output

Content
View full analysis
{ if (el.getAttribute("aria-hidden") === "true") return; if (el.getAttribute("role") === "combobox" && el.getAttribute("aria-autocomplete") === "list") return; const tag = el.tagName; const type = (el.type || "").toLowerCase(); let filled = false; let value = null; if (type === "checkbox" || type === "radio") { filled = el.checked; value = el.checked ? (el.value || "checked") : null; } else if (tag === "SELECT") { const opt = el.options[el.selectedIndex]; value = opt ? opt.text.trim() : null; filled = !!value && value !== ""; } else if (tag === "INPUT" || tag === "TEXTAREA") { value = el.value.trim() || null; filled = !!value; } else if (tag === "DIV" || tag === "SPAN") { const text = (el.innerText || el.textContent || "").trim(); filled = text !== "" && !/attach|upload/i.test(text); value = filled ? text : null; } fields.push({ label: getLabel(el), tag, type: el.type || null, kind: "native", filled, value }); }); // 2. Custom combobox (framework-agnostic) document.querySelectorAll("input[role=\"combobox\"][aria-autocomplete=\"list\"]").forEach(combobox => { if (combobox.getAttribute("aria-required") !== "true") return; const isInvalid = combobox.getAttribute("aria-invalid") === "true"; // Try three methods in order to get the selected value const value = getSentinelValue(combobox) || getAriaSelectedValues(combobox) || getDisplayedValue(combobox) || null; const filled = !!value && !isInvalid; fields.push({ label: getLabel(combobox), tag: "INPUT", type: "combobox", kind: "combobox", id: combobox.id, filled, value }); }); // 3. Return grouped results: unfilled (needs input) a ...[truncated 2913 chars]
Remediation
View remediation
0; } ``` 5. Return only sanitized metadata: ```javascript fields.push({ label: getLabel(el), tag, type: el.type || null, kind: "native", filled }); ``` 6. Add automated tests proving that known secret marker values never appear in serialized evaluation output. 7. Avoid logging raw browser-evaluation output when it may contain application data. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:18
Finding

Runtime Python Dependency Is Not Version-Pinned

Content
View full analysis
Remediation
View remediation
\ --hash=sha256: ``` 3. Configure installation to require hashes and reject unexpected transitive artifacts. 4. Use the official package index through authenticated TLS, and do not permit arbitrary extra indexes. 5. Install the dependency in a dedicated virtual environment with only the filesystem permissions needed to read the selected resume. 6. Review and lock transitive dependencies as well as the direct dependency. 7. Perform dependency vulnerability and provenance checks as part of Skill release validation. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:221
Finding

Predictable Temporary Shell Script Permits File Races and Residual Sensitive Data

Content
View full analysis
"$SCRIPT" << 'SCRIPT_EOF' # Contains only: openclaw browser fill/select/click/upload commands # No network requests, no external downloads, no eval SCRIPT_EOF chmod 700 "$SCRIPT" && bash "$SCRIPT" && rm -f "$SCRIPT" ``` A related instruction in `ERRORS.md`, line 18, reinforces the same workflow: ```markdown | Using `write` tool to create script files | `$(date +%s)` does not expand inside `write` — use `exec` + `cat heredoc` and run with exact path `bash "$SCRIPT"` | ``` ### Technical Analysis The generated script name is based only on the current Unix timestamp in seconds and is therefore predictable. The script is created in the shared `/tmp` directory using ordinary shell redirection, which does not request exclusive creation and can follow a pre-existing symbolic link. A local same-host attacker may pre-create the expected path as a symbolic link, causing the redirection to overwrite another file writable by the Agent account. There is also a time-of-check/time-of-use interval between creation and execution in which another process may attempt to replace or alter the path. The script receives restrictive permissions only after its contents have been created. In addition, cleanup is chained with `&&`, so `rm -f "$SCRIPT"` is not executed if `chmod` or `bash` fails. Failed scripts can remain in `/tmp`. Generated browser commands may contain personal form values, resume paths, target identifiers, or other sensitive application data. The file does not need executable permission because it is invoked explicitly through `bash`. Applying `chmod 700` does not address safe creation, path ownership, or race protection. ### Attack Path #### Symbolic-Link Overwrite 1. A local attacker predicts `/tmp/fill_
Remediation
View remediation
"$SCRIPT" <<'SCRIPT_EOF' # Generated commands SCRIPT_EOF if [ ! -f "$SCRIPT" ] || [ -L "$SCRIPT" ] || [ ! -O "$SCRIPT" ]; then echo "Unsafe temporary script" >&2 exit 1 fi bash "$SCRIPT" ``` For stronger isolation, create a private temporary directory with `mktemp -d`, ensure it is mode `0700`, place the script inside it, and remove the complete directory through an exit trap. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • 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
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description promises full job-application automation: opening pages, filling multi-step forms, uploading documents, submitting applications, and updating a tracker. The supplied code does none of those things. It only queries the DOM for required fields, checks whether they appear filled, and returns grouped results. The script is explicitly read-only and contains no form-writing, clicking, navigation, upload, submission, network, or tracker-update logic. This is a material description-behavior mismatch because the actual code's primary purpose is field validation/auditing, not application autofill and submission.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The declared description promises a complete end-to-end job application automation flow: opening application pages, filling multi-step forms, uploading documents, confirming successful submission, consuming resume_ready jobs from another system, and updating a tracker. The provided code chunk does not implement that full behavior. Instead, it is a generic framework/template for runtime-generated browser automation commands using openclaw. It includes snapshotting, helper functions, sourcing a dropdown-matching helper, and error aggregation, but the actual fill steps are explicitly absent and meant to be injected later. There is also no code in this chunk for selecting jobs, opening application URLs, interacting with jobautopilot-tailor, or marking applications as applied in any tracker. While the template is broadly supportive of form filling and uploads, the concrete behavior shown is materially narrower than the declared purpose, so this chunk does not accurately represent the full described skill behavior.

Content

No source excerpt is available for this finding.

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Generating a shell script in /tmp, executing it, and immediately deleting it in a chained command reduces auditability and increases the risk of unsafe command composition if any interpolated values are not strictly controlled. In this skill's context, the generated script is supposed to contain only browser CLI calls, but because it is dynamically assembled and executed through bash, a bug or prompt-influenced value could turn the batch mechanism into arbitrary command execution.

Content

Scanner excerpt · SKILL.md (reported line 227)May include surrounding context.

Contains only: openclaw browser fill/select/click/upload commands

No network requests, no external downloads, no eval

SCRIPT_EOF chmod 700 "$SCRIPT" && bash "$SCRIPT" && rm -f "$SCRIPT"

text

Scripts are owner-only (`chmod 700`) and deleted immediately after execution.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill declares broad capabilities including shell execution and browser-driven network activity but does not define a restrictive tool scope such as allowed-tools or permissions. In an automation skill that handles sensitive personal data and performs state-changing web actions, this increases the blast radius if the agent is prompted unexpectedly or if helper content is modified, because there is no manifest-level limitation preventing broader tool use.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 227)May include surrounding context.

Contains only: openclaw browser fill/select/click/upload commands

No network requests, no external downloads, no eval

SCRIPT_EOF chmod 700 "$SCRIPT" && bash "$SCRIPT" && rm -f "$SCRIPT"

text

Scripts are owner-only (`chmod 700`) and deleted immediately after execution.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 230)May include surrounding context.

Contains only: openclaw browser fill/select/click/upload commands

No network requests, no external downloads, no eval

SCRIPT_EOF chmod 700 "$SCRIPT" && bash "$SCRIPT" && rm -f "$SCRIPT"

text

Scripts are owner-only (`chmod 700`) and deleted immediately after execution.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation states that all personal data comes from environment variables, but earlier sections instruct the agent to parse resumes from .docx files and extract work history and other personal details at runtime. This inconsistency matters because it understates the actual data-access surface, which can cause reviewers or users to grant broader trust than warranted and may lead to unintended processing of sensitive data from local files.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

L106 says helper scripts are used directly from the skill's scripts folder and that no copying to external paths is required. Later, the documented implementation writes and executes generated shell scripts in /tmp for form filling (L220-L230). While the /tmp scripts are generated rather than copied helper scripts, the earlier wording contradicts the described execution model and could mislead reviewers about filesystem side effects.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.