Back to skill

Security audit

Jobs Hunter Claw

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Google Sheets job tracker, but unsafe CLI input handling can let job or search text execute local code under the user’s account.

Review this skill before installing. Use a dedicated Google account or least-privilege credentials, limit any email/calendar automation to job-related labels and calendars, avoid feeding untrusted recruiter or job-posting text into the CLI until the Python/AWK injection issues are fixed, and back up the spreadsheet before enabling cron or using force-delete.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/job-tracker.sh:275
Finding

Arbitrary Python Code Execution Through Unsafe Argument Interpolation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/job-tracker.sh:631
Finding

Arbitrary Command Execution Through AWK Program Injection in Search

Content
View full analysis
0") else awk_conditions+=("index(\$$idx, \"$query\") > 0") fi fi done local condition condition=$(IFS='||'; echo "${awk_conditions[*]}") local results if $use_fuzzy && command -v fzf &> /dev/null; then # Fuzzy search with fzf results=$(echo "$data" | fzf --filter="$query" 2>/dev/null || true) else results=$(echo "$data" | awk -F'\t' "$condition") fi ``` ### Technical Analysis The search query is concatenated into AWK source code between double quotes. The resulting string is then supplied as the AWK program: ```bash awk -F'\t' "$condition" ``` A query containing AWK string delimiters and valid AWK syntax can escape the intended comparison expression and inject new expressions or actions. AWK provides a `system()` function, so program injection can be converted into operating-system command execution. Both regex and non-regex search paths are affected because both place `$query` directly into generated AWK source. Shell quoting around `$condition` only preserves the argument passed to AWK; it does not prevent AWK from interpreting injected syntax as executable program text. The fuzzy-search branch uses `fzf --filter="$query"` and does not construct AWK source, but the normal search branch remains exploitable. ### Attack Path 1. An attacker causes a crafted string to be used as the positional query for `job-tracker.sh search`. 2. The CLI concatenates that string into one or more AWK conditions. 3. The crafted ...[truncated 1185 chars]
Remediation
View remediation
0) { print next } } } ' ) ``` For regex mode: 1. Continue passing the expression through `-v query="$query"`. 2. Use a fixed expression such as `value ~ query`; AWK treats the variable's value as a dynamic regular expression without parsing it as program source. 3. Handle invalid regular expressions cleanly and return a user-facing error. 4. Consider implementing all search behavior in Python with `re.search()` and positional arguments if consistent regex validation is required. 5. Add tests containing double quotes, braces, semicolons, backslashes, newlines, and AWK keywords such as `system`. 6. Run the skill under least privilege to reduce the consequences of any future parser-related flaw. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/job-tracker-appscript.js:265
Finding

Spreadsheet Formula Injection Through Unsanitized Job and Log Fields

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

brew install steipete/tap/gogcli

Authenticate with Google

gog auth credentials /path/to/client_secret.json gog auth add your@gmail.com --services sheets

text

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

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

for detailed setup.

3. Configure Spreadsheet ID (Required)

Set the environment variable with your Google Sheet ID:

bash
export JOB_TRACKER_SPREADSHEET_ID="your-google-sheet-id"

The ID is found in your Google Sheet URL:

text
https://docs.google.com/spreadsheets/d/[THIS-IS-THE-ID]/edit

For persistent configuration, add to your shell profile (~/.bashrc, ~/.zshrc):

bash
echo 'export JOB_TRACKER_SPREADSHEET_ID="your-google-sheet-id"' >> ~/.bashrc

For OpenClaw agents, set in the agent's environment or TOOLS.md.

Quick Start

bash
# Set your spreadsheet ID first
export JOB_TRACKER_SPREADSHEET_ID="your-google-sheet-id"

# View all commands
./scripts/job-tracker.sh help

# Add a discovered job
./scripts/job-tracker.sh add --company "Morgan Stanley" --role "AI Architect" --source LinkedIn

# List active interviews
./scripts/job-tracker.sh list --status interview

# Log an event
./scripts/job-tracker.sh log JOB002 --event interview_scheduled --details

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · references/google-sheet-setup.md (reported line 78)May include surrounding context.

ds for each job attribute

  • Dropdown for Status (data validation)
  • Dropdown for Event Type (data validation)
  • Reference section showing valid values

Configure the CLI

Set the JOB_TRACKER_SPREADSHEET_ID environment variable:

bash
export JOB_TRACKER_SPREADSHEET_ID="your-spreadsheet-id-here"

For persistent configuration, add to your shell profile (~/.bashrc, ~/.zshrc):

bash
echo 'export JOB_TRACKER_SPREADSHEET_ID="your-spreadsheet-id"' >> ~/.bashrc
source ~/.bashrc

Valid Status Values

Use these exact values (Title Case):

  • Discovered
  • Applied
  • Screening
  • Interview
  • Karat Test Scheduled
  • Offer
  • Rejected
  • Withdrawn
  • Accepted
  • Closed

Valid Event Types

Use these exact values (lowercase):

  • discovered
  • applied
  • recruiter_contact
  • user_reply
  • interview_scheduled
  • interview_completed
  • test_scheduled
  • test_completed
  • offer_received
  • rejection
  • follow_up
  • status_change
  • note

Install Apps Script (Optional)

For form automation in th

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README explicitly advertises cron-based email scans and Google Sheets storage for job-hunting data, but provides no warning about privacy, sensitive personal data, third-party access, or credential handling. For a skill that may process recruiter emails, application history, and potentially personal identifiers, omission of data-handling guidance can lead users to deploy automation that exposes sensitive information or over-collects data without informed consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation explicitly instructs an agent to scan email and check calendar data, which involves access to sensitive personal communications and scheduling information. Without clear privacy warnings, consent requirements, scope limits, or data-handling constraints, an operator may over-grant access and unintentionally expose or process sensitive content.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
79% confidence
Finding

The documented delete ... --force path enables unattended destructive actions in automation, removing job-tracking records without an interactive confirmation step. In an agentic or cron-driven context, mistakes in prompts, identifiers, or logic could cause silent data loss at scale.

Content

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

Delete with confirmation prompt

./scripts/job-tracker.sh delete JOB015

Delete without confirmation (for scripts/automation)

./scripts/job-tracker.sh delete JOB015 --force

text

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This code writes job records to the spreadsheet and then immediately clears the form, but it only shows a success toast after the fact. There is no confirmation prompt or explicit user-facing warning in comments/docstrings that invoking the function will persist data and modify sheet contents.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The save routine overwrites an existing row in the Jobs sheet and may append a status-change log entry, but it does not provide any confirmation before modifying persisted spreadsheet data. The toast appears only after the update, so users are not warned in advance about the write operation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This function blanks all configured form and log cells, which is a potentially destructive operation for in-progress user input. Although a toast is shown afterward, there is no confirmation prompt or pre-action warning that the current form contents will be lost.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/job-tracker.sh (reported line 743)May include surrounding context.

sh
# Delete a job (with confirmation)
  job-tracker delete JOB002

  # Delete without confirmation
  job-tracker delete JOB002 --force

  # Show job details

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The text states that the skill 'requires' a specific model and explicitly says not to use other models, removing user choice rather than presenting a recommendation. Under this rule, forced organizational preference expressed in natural language should be flagged unless clearly justified as a strict compatibility requirement.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The comment and help text describe delete as preserving activity logs, but the implementation clears columns A:P for the row, including column P (log), which the schema labels as the latest 3 log entries formula. While the separate Activity Log sheet is not deleted, the user-visible in-row log history is removed, so the documentation overstates what is preserved.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.