Back to skill

Security audit

Real Estate Spider

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real-estate scraper that openly includes anti-bot and CAPTCHA-bypass workflows, session reuse, and external CAPTCHA-solving examples, so it needs careful review before installation.

Install only if you have permission to collect data from the target sites and are comfortable with automation that may bypass anti-bot controls. Avoid using the CAPTCHA-solving example unless you fully control the image path and provider, do not save authenticated browser sessions unless necessary, and keep generated session files, screenshots, PDFs, and scraped data out of shared folders or source control.

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

T09 · Insecure Skill Coding Practices

Warning
Location
docs/captcha_strategies.md:110
Finding
Unrestricted Local File Upload to an Unspecified CAPTCHA Service<![CDATA[ ## Vulnerability Details **File Location**: `docs/captcha_strategies.md:110-119` and `SKILL.md:339-348` **Vulnerability Type**: Arbitrary readable-file disclosure through an external upload **Risk Level**: Medium ### Vulnerable Code ```python # Use a third-party CAPTCHA recognition API import requests def solve_captcha(image_path): response = requests.post( "https://captcha.service.com/api/solve", files={"image": open(image_path, "rb")}, headers={"Authorization": "Bearer YOUR_API_KEY"} ) return response.json()["solution"] ``` ### Technical Analysis The documented CAPTCHA solver accepts an unrestricted `image_path`, opens that path with the process's current privileges, and transmits its contents to an external service. It does not verify that the resolved path belongs to a dedicated CAPTCHA directory or that the file is actually an image. It also lacks file-size, extension, MIME-type, and symbolic-link validation. Uploading a genuine CAPTCHA image is related to the declared crawler functionality. However, granting the upload routine access to any file readable by the process exceeds the minimum privileges required for that feature. The endpoint is also a placeholder rather than an identified and reviewed provider, so its ownership, retention policy, and data-handling guarantees cannot be established. This is presented as example code rather than an automatically invoked project path. Exploitation therefore requires the example to be adopted or invoked with an attacker-influenced path. ### Attack Path 1. A user integrates or executes the documented `solve_captcha` function. 2. An attacker, untrusted caller, or malformed workflow controls or influences `image_path`. 3. The supplied path points to a sensitive readable file, potentially through a symbolic link or path traversal. 4. `open(image_path, "rb")` reads the file without validation. 5. `requests.post` sends the complete file to the configured external CA ...[truncated 545 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the placeholder third-party integration from the default workflow. 2. Require explicit user approval before transmitting any image to an external provider. 3. Use an allowlisted, documented HTTPS endpoint whose ownership and retention policy have been reviewed. 4. Restrict uploads to a dedicated CAPTCHA directory: - Resolve the candidate path with `Path.resolve()`. - Confirm that it remains beneath the approved directory. - Reject symbolic links and non-regular files. 5. Validate the file extension, decoded image format, MIME type, and maximum size before transmission. 6. Open files with a context manager so handles are always closed. 7. Keep API credentials outside source files and documentation examples, such as in a protected secret store. 8. Log the destination and file metadata without logging the API token or sensitive file contents. A safer implementation should resemble: ```python from pathlib import Path from PIL import Image import requests CAPTCHA_DIR = Path("screenshots/captcha").resolve() MAX_SIZE = 2 * 1024 * 1024 def solve_captcha(image_path, endpoint, api_key): candidate = Path(image_path).resolve() if CAPTCHA_DIR not in candidate.parents: raise ValueError("CAPTCHA image must be inside the approved directory") if not candidate.is_file() or candidate.is_symlink(): raise ValueError("Invalid CAPTCHA file") if candidate.stat().st_size > MAX_SIZE: raise ValueError("CAPTCHA image is too large") with Image.open(candidate) as image: image.verify() with candidate.open("rb") as image_file: response = requests.post( endpoint, files={"image": (candidate.name, image_file, "image/png")}, headers={"Authorization": f"Bearer {api_key}"}, timeout=15, ) response.raise_for_status() return response.json()["solution"] ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/bypass_real_estate.sh:147
Finding
Browser Session State Is Persisted Without Access Controls or Cleanup<![CDATA[ ## Vulnerability Details **File Location**: `scripts/bypass_real_estate.sh:147-148`; related configuration and instructions at `config/real_estate_config.py:142-146`, `SKILL.md:282-286`, and `docs/captcha_strategies.md:43-63` **Vulnerability Type**: Plaintext persistence of reusable browser session material **Risk Level**: Medium ### Vulnerable Code ```bash echo "13. Save session state" agent-browser state save "$WEBSITE_session.json" ``` The corresponding default configuration enables session persistence and restoration: ```python SESSION_CONFIG = { "save_session": True, "session_file": "real_estate_session.json", "restore_session": True } ``` The Skill instructions also recommend saving and loading state: ```bash agent-browser cookies set "session_id" "your_session_value" agent-browser state save "real_estate_session.json" agent-browser state load "real_estate_session.json" ``` ### Technical Analysis Browser state files can contain cookies, local-storage values, verification tokens, and other session artifacts. The script saves this state under a predictable filename in the current working directory. It does not create a private storage directory, establish restrictive permissions, encrypt the data, impose an expiry time, or remove the state after use. Session reuse is relevant to avoiding repeated CAPTCHA challenges. However, enabling state persistence by default and leaving reusable material in ordinary project output exceeds the minimum storage needed for a one-time crawl. This behavior is local session persistence, not operating-system persistence or Agent memory poisoning. The project does not install startup services, scheduled tasks, or cross-session instruction hooks. ### Attack Path 1. The user completes a CAPTCHA or accesses a site using an authenticated browser session. 2. The script invokes `agent-browser state save`. 3. Cookies or equivalent browser tokens are written to a predictable JSON file. 4. The file remai ...[truncated 776 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable browser-state persistence by default and require an explicit opt-in flag. 2. Do not save authenticated state when anonymous crawling is sufficient. 3. Store state in a dedicated per-user directory rather than the project directory. 4. Create the storage directory with mode `0700` and the state file with mode `0600`. 5. Use unpredictable filenames and prevent symbolic-link following where supported. 6. Establish a short expiry time and delete the file immediately after the crawl. 7. Add session-state filenames to `.gitignore` and backup exclusion rules. 8. Warn users that state files may contain reusable authentication material. 9. Prefer server-scoped, short-lived cookies and invalidate saved sessions after use. 10. If longer retention is essential, encrypt the state using an operating-system-backed credential store rather than a hardcoded key. For example: ```bash STATE_DIR="${XDG_RUNTIME_DIR:-$HOME/.cache}/real-estate-spider" umask 077 mkdir -p "$STATE_DIR" STATE_FILE="$(mktemp "$STATE_DIR/session.XXXXXX.json")" agent-browser state save "$STATE_FILE" cleanup() { rm -f -- "$STATE_FILE" } trap cleanup EXIT INT TERM ``` ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:28
Finding
Third-Party Dependencies Are Installed Without Version or Integrity Pinning<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:28-33`; additional instructions at `README.md:45` and `scripts/bypass_real_estate.sh:48-52` **Vulnerability Type**: Uncontrolled dependency resolution and global package installation **Risk Level**: Medium ### Vulnerable Code ```bash # Install Python requests library pip install requests beautifulsoup4 lxml ``` The README expands the unpinned installation set: ```bash pip install requests beautifulsoup4 lxml pandas ``` The shell script recommends a global npm installation: ```bash if ! command -v agent-browser &> /dev/null; then echo "agent-browser is not installed" echo "Please run first: npm install -g agent-browser" exit 1 fi ``` ### Technical Analysis The dependency instructions do not specify reviewed versions, hashes, lockfiles, or a trusted registry. Consequently, installation resolves mutable package versions at execution time. A future compromised package release, registry account takeover, or incompatible update could introduce code that was not present during this audit. The global npm recommendation increases exposure because it installs a mutable executable into a user-wide or system-wide command path. Depending on local npm configuration, the installation may also require elevated privileges. No evidence shows a currently malicious or typosquatted package name. The risk arises from unsafe supply-chain controls rather than a confirmed malicious dependency. ### Attack Path 1. A user follows the documented installation instructions. 2. `pip` or `npm` queries the configured package registry and resolves the latest matching release. 3. A package release, transitive dependency, publisher account, or registry response has been compromised after the Skill was reviewed. 4. Installation hooks or imported package code execute with the installing user's privileges. 5. The compromised dependency gains access to the crawler's files, browser state, network connection, and any ...[truncated 672 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Provide a reviewed `requirements.txt`, `pyproject.toml`, or lockfile with exact versions. 2. Generate and verify cryptographic hashes for Python packages, for example with `pip-tools` and `pip install --require-hashes`. 3. Pin the `agent-browser` version rather than installing the mutable latest release. 4. Document the expected registry, publisher, and package provenance. 5. Use an isolated Python virtual environment. 6. Install the browser tool locally to the project or in a dedicated user environment instead of globally. 7. Do not recommend administrator or root installation. 8. Use dependency scanning and scheduled review before updating pins. 9. Record transitive dependencies in the lockfile so audit results remain reproducible. 10. Consider distributing a signed, reproducible environment manifest. Example: ```bash python3 -m venv .venv . .venv/bin/activate python -m pip install --require-hashes -r requirements.txt npm install --save-exact agent-browser@<reviewed-version> ``` ]]>

T09 · Insecure Skill Coding Practices

Note
Location
main.py:98
Finding
Shell Invocation of an Unquoted Project Path<![CDATA[ ## Vulnerability Details **File Location**: `main.py:98-104` **Vulnerability Type**: Path-based command injection through unnecessary shell interpretation **Risk Level**: Low ### Vulnerable Code ```python script_path = os.path.join(os.path.dirname(__file__), "scripts/bypass_real_estate.sh") # Build command command = f"bash {script_path}" print(f"Executing command: {command}") import subprocess result = subprocess.run(command, shell=True, capture_output=True, text=True) ``` ### Technical Analysis The code constructs a command string containing an unquoted filesystem path and executes it with `shell=True`. Although command-line arguments such as `city` and `district` do not enter this command, the project's installation path is interpreted as shell syntax. If the project resides in a path containing shell metacharacters, spaces, substitutions, or command separators, the shell may parse that path as additional arguments or commands. Shell execution is unnecessary because the program only needs to invoke `bash` with one script path. The practical exposure is lower than a typical remotely controlled command injection because exploitation requires influence over the project path or deployment layout. ### Attack Path 1. An attacker causes the project to be extracted, cloned, mounted, or referenced from a directory name containing shell syntax. 2. The user runs `main.py` with `--mode agent-browser`. 3. The project computes `script_path` from the attacker-influenced installation path. 4. The unquoted path is concatenated into `command`. 5. `subprocess.run(..., shell=True)` asks the shell to parse the complete string. 6. Embedded shell syntax executes with the privileges of the user running the crawler. For example, a maliciously crafted directory name containing a command separator could cause the shell to treat part of the path as a second command. ### Impact Assessment Successful exploitation permits arbitrary command execution with the privileg ...[truncated 368 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not invoke a shell. Pass the executable and script path as separate arguments: ```python script_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "scripts", "bypass_real_estate.sh", ) result = subprocess.run( ["bash", script_path], capture_output=True, text=True, check=False, ) ``` Additional hardening should include: 1. Resolve and validate the script path before execution. 2. Confirm that it is a regular file located beneath the expected project directory. 3. Reject symbolic links if the project deployment model does not require them. 4. Avoid incorporating future user-controlled values into command strings. 5. If arguments are later passed to the script, add each value as a separate list element. 6. Consider invoking the required browser operations directly from Python to eliminate the shell-script trust boundary entirely. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (60)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
声明将该技能描述为面向多个中国房产中介网站的通用数据爬虫,并强调自动数据提取。实际代码却仅是一个 shell 脚本,用于链家站点的验证码应对和访问准备:检查 agent-browser、设置特定 cookie、设置浏览器头、访问链家页面、模拟用户操作、截图与快照、提示人工完成验证码、保存已验证会话。其主要目的不是通用爬虫,也没有实现房源数据解析、抽取或多平台适配。虽然“包含反爬虫策略”与代码部分吻合,但整体描述显著夸大并偏离了实际行为,因此应判定为不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The declared description promises a universal crawler for several Chinese real-estate websites with anti-crawling handling and automatic data extraction. The supplied code is much narrower: it is a test script for Beike only, using agent-browser to mimic a real browser, visit the homepage, capture a screenshot, and inspect page metadata/elements. While setting realistic headers can be considered part of anti-bot behavior, the main behavior shown is browser automation/testing rather than multi-site crawling or automatic extraction. This is a material description-versus-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
声明描述的是一个面向多个中国房产中介网站的“通用爬虫技能”,重点包括多站点支持、反爬虫策略和自动化数据提取。实际代码仅测试 `https://bj.ke.com/ershoufang` 这一个贝壳找房页面,且是面向北京二手房页的实验性抓取与解析脚本。虽然它确实属于房产网站爬取相关代码,也包含基础请求头伪装、随机等待和字段提取,但范围和成熟度都明显低于声明:没有安居客、搜房网、链家支持,没有可见的通用框架,也没有较完整的反爬或自动提取实现。因此描述与实际行为存在实质性不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
声明描述的是一个“专业”“通用”的中国房产中介网站爬虫技能,重点应是多平台数据抓取、反爬策略和自动数据提取。实际代码只是一个 shell 测试脚本,专门针对链家北京二手房页面进行 agent-browser 可用性与页面访问测试,包含设置请求头、滚动、截图、文本抓取、检查验证码文案、尝试点击筛选和搜索。虽然其中确实涉及反爬相关操作(浏览器指纹、验证码检查)并与房产网站有关,但缺少通用爬虫应有的多站点支持、稳定抓取逻辑、结构化解析与自动提取流程。因此代码与声明存在实质性偏差,属于描述与实际行为不匹配。

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The guidance to use real cookies obtained after manual verification, spoof referers, use proxies, and limit frequency is explicitly tailored to bypass stronger defenses such as CAPTCHA and origin checks. In this skill context, that materially increases the likelihood of evading access controls rather than simply automating legitimate browsing.

Natural-Language Policy Violations

High
Confidence
99% confidence
Finding
The document is broadly framed as operational guidance for bypassing CAPTCHA and anti-bot protections, including fingerprint simulation, saved verified sessions, proxy rotation, and navigation strategies to reach protected pages. In a scraping skill, that transforms the skill from data extraction into access-control circumvention guidance.

Ssd 2

High
Confidence
96% confidence
Finding
The opening sections provide practical, actionable anti-detection steps such as mobile UA selection, device fingerprint setup, and simulated human behavior. These instructions are semantically clear operational evasion guidance even without explicit harmful keywords.

Ssd 4

High
Confidence
95% confidence
Finding
This workflow normalizes CAPTCHA bypass by instructing users to manually solve once, save the verified session, and reuse it for subsequent automated access. That creates a repeatable mechanism for extending past an access challenge and undermines the protective purpose of the verification step.

Ssd 2

High
Confidence
98% confidence
Finding
The proxy-rotation and timing-control sections are classic anti-abuse evasion measures designed to avoid rate limits and bot detection. In context, they directly support sustained scraping against protected targets while reducing the chance of detection or blocking.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
This section explicitly documents use of a third-party CAPTCHA-solving service to automate challenge completion, which is a direct anti-bot evasion capability rather than ordinary real-estate data extraction. In the context of a scraping skill targeting commercial property sites, this materially enables circumvention of access controls and can facilitate unauthorized collection at scale.

Ssd 2

High
Confidence
99% confidence
Finding
The CAPTCHA-solving API snippet operationalizes automated challenge bypass with working code structure, making abuse straightforward. This is especially dangerous because it lowers the skill barrier for evading website protections at scale.

Lp1

High
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The file has shell-execution capability via subprocess, but that capability is not declared in permissions. Undeclared privileged behavior is dangerous in agent environments because reviewers and users cannot accurately assess what the skill is allowed to do, and shell access can be used to run arbitrary local commands or chained scripts.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
print(f"执行命令: {command}")
        
        import subprocess
        result = subprocess.run(command, shell=True, capture_output=True, text=True)
        
        if result.returncode == 0:
            print("agent-browser脚本执行成功")
Confidence
90% confidence
Finding
This is a true tool-parameter abuse pattern because subprocess is invoked with shell=True, which grants shell parsing and metacharacter handling to the command string. Even if the current string is constant-like, this pattern is risky in agent code because minor future changes or path manipulation can convert it into command injection or unintended command execution.

Lp1

High
Category
MCP Least Privilege
Confidence
85% confidence
Finding
The script performs live browser-driven network access to lianjia.com and related pages, but the capability is not declared in permissions. Undeclared network behavior reduces reviewability and can enable unexpected external communication, especially in a skill that also persists session state and cookies.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
This script is explicitly designed to evade a site's anti-bot and CAPTCHA protections through cookie seeding, user-agent/header spoofing, behavioral simulation, proxy use, and session reuse. Those measures are access-control evasion tactics that can facilitate unauthorized scraping, reduce detection, and scale abuse against the target platform.

Natural-Language Policy Violations

High
Confidence
98% confidence
Finding
The script's labeling and instructions clearly frame the workflow as CAPTCHA bypassing, which indicates deliberate evasion of a website's access controls. In a scraping skill targeting commercial real-estate sites, this materially increases risk because it operationalizes unauthorized collection and concealment techniques rather than ordinary browsing.

Missing User Warnings

High
Confidence
98% confidence
Finding
Saving browser session state can persist cookies, tokens, and other authentication-related material, which may later be reused to access accounts or bypass fresh authentication. Because the script does this without a specific warning or opt-in, it creates a meaningful risk of credential-related persistence and session theft from the local filesystem.

Lp1

High
Category
MCP Least Privilege
Confidence
96% confidence
Finding
The script writes crawler output to user-specified JSON/CSV files, but this file-write capability is not declared in the skill permissions. Undeclared write access is dangerous because it expands the skill's effective capabilities, can overwrite local files if misused, and prevents users or hosts from accurately assessing what the skill is allowed to do.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The script checks for CAPTCHA-related text and explicitly tells the operator to manually complete the challenge so browsing can continue. CAPTCHA exists as an access-control and abuse-prevention mechanism, so instructing continuation after challenge presentation facilitates circumvention of the site's protections.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The README states that the skill saves session state, screenshots, and scraped data, but it does not clearly and prominently warn users about what sensitive artifacts may be persisted to disk or the security/privacy implications. In a crawler that explicitly includes cookie/session management and anti-bot bypass workflows, saved files can contain authentication tokens, browsing state, or regulated/sensitive data that could later be exposed to other tools, users, or processes on the same system.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The trigger conditions are broad enough that the skill may activate for generic scraping requests, including requests to bypass anti-bot protections, without clear user intent boundaries. In an agent setting, over-broad activation increases the chance of the model selecting risky automation that performs policy-sensitive actions against third-party sites.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The examples hard-code Chinese locale behavior through defaults like city='北京' and the 'Accept-Language: zh-CN,zh;q=0.9' header, and the skill description is entirely framed for Chinese sites without opt-in language selection. This is a natural-language locale policy issue because the skill imposes a specific language/locale rather than offering the user a choice or clearly documenting a justified locale constraint.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill recommends sending CAPTCHA images to a third-party solving service without warning that screenshots may contain personal data, account state, or other sensitive page content. This creates a real data exfiltration risk because users may unknowingly transmit protected information off-device to an untrusted external processor.

External Transmission

Medium
Category
Data Exfiltration
Content
def solve_captcha(image_path):
    # 上传验证码图片到识别服务
    response = requests.post(
        "https://captcha.service.com/api/solve",
        files={"image": open(image_path, "rb")}
    )
Confidence
97% confidence
Finding
The code performs an external POST of an image file to a third-party CAPTCHA-solving endpoint, which is direct off-device data transmission. Because the uploaded image may contain sensitive or account-linked information and the endpoint is external, this creates a concrete confidentiality risk in the skill context.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The natural-language description and read_when conditions are written only in Chinese and target China-specific websites, but the manifest does not state that the skill is region-specific or offer any language/locale choice. Per the policy, forcing a specific language or locale without opt-in or clear documented justification is a natural-language policy concern.

Static analysis

No suspicious patterns detected.