Back to skill

Security audit

Craigslist Monitor

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed Craigslist lead-scraper with optional saving and scheduling, but users should be aware it stores contact leads locally and enrichment follows listing URLs without strong validation.

Install only if you are comfortable with a scraper making outbound Craigslist requests and, when --save is used, appending lead/contact details to a local markdown file. Avoid scheduled use unless you intend recurring weekly runs, and be cautious with --enrich until listing URL validation is added.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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 (2)

T06 · System Persistence

Note
Location
SKILL.md:47
Finding
Documented Cron Configuration Creates Persistent Scheduled Execution<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:47-50` **Vulnerability Type**: Persistent scheduled task **Risk Level**: Low ### Vulnerable Code ```text Run weekly on Mondays to catch fresh Craigslist posts: ``` openclaw cron add --schedule "0 8 * * MON" --command "python3 ~/StudioBrain/00_SYSTEM/skills/craigslist-monitor/monitor.py --save" ``` ``` ### Technical Analysis The documentation instructs the user to register the skill as a recurring cron task. Once configured, the scraper survives the original interactive session and executes every Monday without requiring approval for each run. The scheduled command performs outbound Craigslist requests and appends results to a persistent local lead file. The scheduling behavior is consistent with the advertised monitoring purpose and is not installed automatically by `monitor.py`; exploitation therefore requires a user or agent to follow the documented command. Nevertheless, it creates cross-session persistence and should be accompanied by explicit consent, lifecycle controls, and removal instructions. ### Attack Path 1. A user or agent follows the scheduled-use instructions in `SKILL.md`. 2. `openclaw cron add` registers the Python command as a recurring task. 3. The task remains active after the initial skill session ends. 4. Every Monday, the script makes network requests and, through `--save`, appends collected listing and contact information to `MASTER_LEAD_LIST.md`. 5. Execution continues until the scheduled task is explicitly removed. ### Impact Assessment The persistent task executes with the permissions of the account that registered it. It can repeatedly: - Make outbound HTTP requests. - Read data returned by Craigslist. - Create the configured parent directories when permitted. - Append data to the configured lead-list file. - Consume network, storage, and processing resources. The shown task does not elevate privileges or establish an external command-and-control channel. Its ...[truncated 113 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Clearly label scheduling as optional and explain that it creates persistent recurring execution. - Require explicit informed confirmation before an agent registers the task. - Document commands for listing, disabling, and deleting the scheduled task. - Use a distinctive task name so users can identify and remove it reliably. - Run the task under a dedicated least-privilege account with access only to the required output directory. - Add retention limits, duplicate suppression, and maximum file-size controls for the appended lead data. - Record each scheduled execution in a user-visible audit log. - Consider requiring periodic reauthorization rather than creating an indefinitely active schedule. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
monitor.py:118
Finding
Unvalidated Listing URLs Can Be Fetched During Phone Enrichment<![CDATA[ ## Vulnerability Details **File Location**: `monitor.py:118-121, 144-149, 165-168` **Vulnerability Type**: Server-Side Request Forgery through unvalidated remote URLs **Risk Level**: Medium ### Vulnerable Code ```python # URL link_el = item.css('a') url = "" if link_el: url = link_el[0].attrib.get('href', '') ``` ```python def fetch_ad_phone(url: str) -> str: """Fetch individual ad page to find phone number.""" if not url: return "" page = fetch_page(url) if not page: return "" body = page.css('body') text = body[0].get_all_text() if body else "" return extract_phone(text) ``` ```python if enrich_phone: for lead in leads: if not lead["phone"] and lead["url"]: p = fetch_ad_phone(lead["url"]) if p: lead["phone"] = p print(f" 📞 {p} → {lead['title'][:40]}") ``` The request function used by this flow performs no destination validation: ```python def fetch_page(url: str): try: return Fetcher.get(url, stealthy_headers=True, impersonate='chrome', timeout=30) except Exception as e: print(f" [fetch error] {e}", file=sys.stderr) return None ``` ### Technical Analysis The scraper extracts the first anchor's `href` from remotely supplied search-result HTML and stores it without validating its scheme, hostname, port, or resolved IP address. When `--enrich` is enabled, that URL is passed directly to `Fetcher.get`. Consequently, a manipulated or unexpected listing URL could cause the host running the scraper to issue a request to a destination other than Craigslist. Depending on the HTTP client's URL and redirect behavior, possible targets include public attacker-controlled servers or services reachable only from the local environment. This is an SSRF-style request primitive. Exploitation requires an attacker to influence the parsed search-result anchor or otherwise supply manipulated page content. The co ...[truncated 1829 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Parse every listing URL with a standards-compliant URL parser before requesting it. - Resolve relative links against the expected Craigslist origin. - Permit only the `https` scheme. - Maintain an explicit allowlist of expected Craigslist hostnames, such as the required regional Craigslist domains. - Reject URLs containing embedded credentials, fragments used unexpectedly, nonstandard ports, malformed hostnames, or unsupported schemes. - Resolve the hostname and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 addresses. - Revalidate the destination after DNS resolution and immediately before connection to reduce DNS-rebinding risk. - Disable redirects where possible. Otherwise, validate every redirect target using the same scheme, hostname, port, and IP-address rules. - Set strict connection, response-size, and redirect-count limits. - Prefer extracting canonical ad identifiers and constructing the expected Craigslist URL locally rather than trusting an arbitrary `href`. - Add tests covering external hosts, private IP addresses, IPv6 loopback, encoded host representations, user-info URLs, unusual ports, protocol-relative links, and redirects outside the allowlist. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (3)

Missing User Warnings

Medium
Confidence
84% confidence
Finding
When --enrich is used, the code performs extra HTTP fetches against individual ad URLs and extracts phone numbers from page bodies. The help text says it will 'find phone numbers,' but it does not explicitly warn that this triggers additional network access and collection of contact information from ad content.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This code writes collected lead details, including phone numbers, locations, and URLs, to a persistent markdown file. While the CLI flag name suggests saving, there is no explicit warning in the code comments, help text, or output that contact data will be stored on disk in a specific internal path.

Missing User Warnings

Low
Confidence
81% confidence
Finding
This markdown file documents a file-writing behavior by stating that --save appends to MASTER_LEAD_LIST.md, but it presents the action as a feature without any caution about modifying persistent internal data. Under the markdown-file warning criterion, behaviors affecting user data or system state should be disclosed with a warning, especially for scheduled or repeated use.

Static analysis

No suspicious patterns detected.