Back to skill

Security audit

OfferCatcher

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to match its recruiting-email reminder purpose, but it uses risky installation patterns and broad email access that users should review before installing.

Install only through ClawHub or a pinned, verified release, not the documented curl-to-bash path. Before use, configure a dedicated recruiting mailbox/account, keep days and max_results small, understand whether your OpenClaw LLM is local or remote, and avoid invoking the helper clear-list or custom --output options unless you fully intend those effects.

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 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
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
README.md:57
Finding

Mutable Remote Installation Script Is Executed Directly by a Shell

Content
View full analysis
Remediation
View remediation
' offercatcher-install.sh | shasum -a 256 --check less offercatcher-install.sh bash offercatcher-install.sh ``` 5. Prefer the documented ClawHub installation mechanism if it verifies package identity and integrity. 6. Pin documentation to a specific release rather than the mutable `main` branch. 7. Protect release publication with signed tags, branch protection, mandatory review, and multi-factor authentication. ]]>

T08 · Insecure Dependencies

Error
Location
install.sh:16
Finding

Installer Clones and Updates Executable Skill Code from an Unpinned Branch

Content
View full analysis
Remediation
View remediation
' test "$(git rev-parse HEAD)" = '' ``` 3. Prefer signed tags and verify them with `git tag -v` or `git verify-commit`. 4. Do not run `git pull` as an implicit update mechanism. 5. Present available updates and their diffs to the user, then require explicit approval. 6. Publish checksums for all executable files or the complete release archive. 7. Add repository branch protection, mandatory reviews, signed release automation, and restricted maintainer access. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/recruiting_sync.py:534
Finding

Scanner Collects Unrelated Recent Email Bodies Before Establishing Recruiting Relevance

Content
View full analysis
cutoff then', 'set msgId to (id of m) as string', 'set subj to subject of m as string', 'set sndr to sender of m as string', 'set ts to (date received of m) as string', ] ``` Bodies are then fetched for every selected message, subject only to a character limit: ```python script = [ f"with timeout of {MAIL_TIMEOUT_SECONDS * 2} seconds", 'tell application "Mail"', f'set targetIds to {{{ids_list}}}', f'set acc to account "{escaped_account}"', f'set mbx to mailbox "{escaped_mailbox}" of acc', 'set results to ""', 'repeat with m in messages of mbx', 'set msgId to id of m as string', 'if targetIds contains msgId then', 'set c to content of m', f'if (length of c) > {MAIL_BODY_LIMIT} then set c to text 1 thru {MAIL_BODY_LIMIT} of c', 'set results to results & msgId & tab & c & character id 0', 'end if', 'end repeat', 'return results', 'end tell', 'end timeout', ] ``` The complete selected content is emitted as JSON for LLM parsing: ```python messages = list_recent_mail_messages( args.days, ...[truncated 3043 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/recruiting_sync.py:416
Finding

Caller-Controlled State Output Can Overwrite Files Outside the Documented State Directory

Content
View full analysis
Path: resolved = path.expanduser().resolve() home = Path.home().resolve() allowed_roots = [ home, Path("/tmp").resolve(), Path(os.environ.get("TMPDIR", "/tmp")).resolve(), ] for root in allowed_roots: try: resolved.relative_to(root) return resolved except ValueError: continue original_str = str(path) if ( ".." in original_str or original_str.startswith("/etc") or original_str.startswith("/var") ): raise SystemExit( f"Path {path} may pose a security risk; refusing access" ) return resolved ``` The accepted location is subsequently overwritten with JSON state: ```python def write_state(state: dict[str, Any], path: Path) -> None: validated_path = validate_path_in_home(path) validated_path.parent.mkdir(parents=True, exist_ok=True) validated_path.write_text( json.dumps(state, ensure_ascii=False, indent=2) + "\n", encoding="utf-8", ) ``` The path is caller-controlled through `--output`: ```python parser.add_argument( "--output", default=str(STATE_PATH), help="State file path", ) ``` The auxiliary `manual_event.py` implementation has no equivalent path validation: ```python def write_state(path: Path, state: dict) -> None: path.parent.mkdir(parents=True, exist_ok=True) path.write_text( ...[truncated 2360 chars]
Remediation
View remediation
Path: resolved = path.expanduser().resolve(strict=False) try: resolved.relative_to(STATE_ROOT) except ValueError as exc: raise SystemExit( f"Output must remain under {STATE_ROOT}" ) from exc return resolved ``` 3. Apply the same validation in `manual_event.py`. 4. If custom state paths are not required, remove the `--output` option entirely. 5. Reject symbolic links for the destination and relevant parent components. 6. Write atomically by creating a temporary file in the approved directory, setting restrictive permissions, flushing it, and replacing the final state file. 7. Set state-file permissions to user-only access, such as mode `0600`. 8. Validate the existing state schema before rewriting it and fail closed on unexpected content. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (56)

Chaining Abuse

High
Category
Tool Misuse
Confidence
94% confidence
Finding

The shell pipeline into bash is a dangerous command-chaining pattern because it converts downloaded content directly into execution without validation, making abuse trivial if upstream content changes. In context, the skill is intended for end users on macOS and likely runs with the user's permissions, so exploitation could lead to code execution, persistence, and access to mail/reminder data.

Content

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

bash
# Install
curl -sSL https://raw.githubusercontent.com/NissonCX/offercatcher/main/install.sh | bash

# Configure
echo 'mail_account: "Gmail"' >> ~/.openclaw/offercatcher.yaml

Chaining Abuse

High
Category
Tool Misuse
Confidence
94% confidence
Finding

This repeated pipe-to-bash command presents the same chaining-abuse risk and normalizes an unsafe installation practice for users. Because this skill later processes email and writes reminders, any compromise at install time can subvert the entire workflow and silently harvest sensitive personal communications.

Content

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

Option 2: One-Line Install

bash
curl -sSL https://raw.githubusercontent.com/NissonCX/offercatcher/main/install.sh | bash

Option 3: Manual Install

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The '| bash' chain turns a remote content fetch directly into shell execution with no inspection boundary. In the context of a mailbox-scanning macOS automation skill, compromise of the fetched script could give an attacker code execution on a host with access to Mail, Reminders, local files, and possibly iCloud-synced data.

Content

Scanner excerpt · README_CN.md (reported line 60)May include surrounding context.

bash
# 安装
curl -sSL https://raw.githubusercontent.com/NissonCX/offercatcher/main/install.sh | bash

# 配置
echo 'mail_account: "Gmail"' >> ~/.openclaw/offercatcher.yaml

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

This direct command chain repeats the same arbitrary-code-execution risk in the dedicated installation section, making it especially likely to be followed. Because the skill is designed to access sensitive mailbox content and create reminders, successful exploitation could expose personal communications and manipulate user data beyond initial installation.

Content

Scanner excerpt · README_CN.md (reported line 92)May include surrounding context.

方式二:一键安装

bash
curl -sSL https://raw.githubusercontent.com/NissonCX/offercatcher/main/install.sh | bash

方式三:手动安装

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill claims AI parsing and sync behavior, but the detected behavior suggests manual event/reminder creation with local state persistence and no evidence of email ingestion. This can mislead users into granting trust to a workflow that behaves differently and stores undeclared local tracking data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill claims AI parsing and sync behavior, but the detected behavior suggests manual event/reminder creation with local state persistence and no evidence of email ingestion. This can mislead users into granting trust to a workflow that behaves differently and stores undeclared local tracking data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill claims AI parsing and sync behavior, but the detected behavior suggests manual event/reminder creation with local state persistence and no evidence of email ingestion. This can mislead users into granting trust to a workflow that behaves differently and stores undeclared local tracking data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill claims AI parsing and sync behavior, but the detected behavior suggests manual event/reminder creation with local state persistence and no evidence of email ingestion. This can mislead users into granting trust to a workflow that behaves differently and stores undeclared local tracking data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill claims AI parsing and sync behavior, but the detected behavior suggests manual event/reminder creation with local state persistence and no evidence of email ingestion. This can mislead users into granting trust to a workflow that behaves differently and stores undeclared local tracking data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill claims AI parsing and sync behavior, but the detected behavior suggests manual event/reminder creation with local state persistence and no evidence of email ingestion. This can mislead users into granting trust to a workflow that behaves differently and stores undeclared local tracking data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The skill claims AI parsing and sync behavior, but the detected behavior suggests manual event/reminder creation with local state persistence and no evidence of email ingestion. This can mislead users into granting trust to a workflow that behaves differently and stores undeclared local tracking data.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

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

  • notes: Additional info
text

## Output Rules

- Reminder title: Company + Event type (e.g., "Google Interview", "Meta Coding Test")
- Include: Time, role, link in notes

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · assets/banner.svg (reported line 3)May include surrounding context.

text
<svg width="800" height="280" viewBox="0 0 800 280" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <!-- 超炫渐变 - 主标题 -->
    <linearGradient id="megaGrad" x1="0%" y1="0%" x2="100%" y2="100%">
      <stop offset="0%" stop-color="#FF0080">
        <animate attributeName="stop-color" values="#FF0080;#7928CA;#FF0080" dur="4s" repeatCount="indefinite"/>

Chaining Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

Using '| bash' creates an unsafe execution chain where unreviewed network content is executed immediately in a shell. In the context of an install script for a skill that also clones and updates code from a remote repository, this increases the blast radius because compromise of the upstream content can lead to arbitrary command execution on the user's machine during installation.

Content

Scanner excerpt · install.sh (reported line 3)May include surrounding context.

sh
#!/bin/bash
# OfferCatcher 一键安装脚本
# 用法: curl -sSL https://raw.githubusercontent.com/NissonCX/offercatcher/main/install.sh | bash

set -e

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The clear-list command deletes every reminder in the specified list in a loop, creating an immediate destructive primitive. Because the skill is supposed to sync recruiting emails, giving it a bulk-wipe capability is unnecessarily dangerous; if invoked accidentally or abusively, it can erase important user data at scale.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The bulk clear-list operation deletes all reminders in a list with no warning, confirmation, or ownership validation. In this skill context, that is especially risky because a recruiting-email helper has no clear need to destroy unrelated reminders, so the feature materially increases the chance of catastrophic user-data loss.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation states that raw Apple Mail content is scanned and then parsed by an LLM, but it does not explicitly warn that emails may contain sensitive personal, employment, or account data. In this skill context, that omission is security-relevant because users may unknowingly expose private mailbox contents to an AI processing pipeline or external component without informed consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The examples show both dry-run and live apply commands, but do not clearly emphasize that the non-dry-run command will create or modify Apple Reminders data. In a workflow driven by LLM-parsed events, unclear documentation increases the chance of unintended writes, duplicate reminders, or persistence of malformed data derived from email content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README promotes automatic scanning of email contents and LLM-based parsing but does not warn users that potentially sensitive recruiting emails may be transmitted to, or processed by, an AI system. In this skill’s context, emails can contain personal data, interview links, contact details, and assessment information, so omission of a privacy/data-handling warning can lead to unsafe deployment and unintended disclosure.

Content

No source excerpt is available for this finding.

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 121)May include surrounding context.

Step 2: Configure

Create ~/.openclaw/offercatcher.yaml:

yaml
mail_account: "Gmail"    # Your Apple Mail account name

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The README describes automatic mailbox scanning and AI parsing but does not clearly warn users that email contents may be sent to an LLM or otherwise exposed to external AI processing. Recruiting emails commonly contain sensitive personal data, interview links, deadlines, and employer information, so missing disclosure materially increases privacy and consent risk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill advertises shell, file, and environment-capable behavior but declares no explicit tool scope or permissions boundary. That creates an authorization gap where an agent may execute sensitive local operations without clear user consent or sandboxing expectations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill handles private email and explicitly routes email bodies into an LLM parsing step, yet it provides no user warning about scanning sensitive mailbox contents or sharing them with a model. In a recruiting context, emails may contain personal identifiers, interview schedules, links, and confidential hiring materials, making the omission materially risky.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The parsing prompt asks the LLM to process full email bodies and return structured fields plus free-form notes, without constraints to suppress sensitive information. That increases the chance of reproducing confidential email content, assessment links, personal data, or secrets in model outputs or downstream reminder notes.

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/apple_reminders_bridge.py (reported line 36)May include surrounding context.

python
cmd = ["osascript"]
    for line in lines:
        cmd.extend(["-e", line])
    return subprocess.run(
        cmd,
        capture_output=True,
        text=True,

Static analysis

No suspicious patterns detected.