Back to skill

Security audit

Browser Web Search

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed web-search/browser-session tool, but its own documentation still points users toward paths that bypass its safety launcher and safer install flow.

Install only if you are comfortable with a third-party npm package operating inside an OpenClaw browser profile. Use the bws-skill/scripts/run.js path rather than direct bws site commands, install with --ignore-scripts, keep BWS_PUBLIC_ONLY=1 unless you intentionally need authenticated adapters, and use a dedicated browser profile with unrelated logged-in tabs closed.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
README.md:8
Finding

Documented Direct Invocation Bypasses the Launcher's Security Controls

Content
View full analysis

Vulnerability Details

File Location: README.md:8-23
Vulnerability Type: Authorization and integrity-control bypass
Risk Level: High

The primary usage documentation directs users and AI agents to invoke the third-party bws executable directly instead of invoking scripts/run.js. Direct invocation bypasses all security controls implemented by the launcher.

Complete vulnerable code snippet:

bash
# Install
npm install -g browser-web-search@0.4.3

# View all commands
bws site list

# Search examples
bws site toutiao/search "ai search"             # Toutiao
bws site zhihu/search "ai agent" --count 5      # Zhihu
bws site hn/search "llm" --sort date            # Hacker News
bws site github/search "ai search" --sort stars # GitHub
bws site youtube/search "ai agent"              # YouTube

# jq filtering
bws site zhihu/search "ai" --jq '[.items[].url]'

Equivalent direct-invocation examples also appear in SKILL.md:218-235, SKILL.md:426-427, SKILL.md:649-659, and SKILL.md:691-693.

Technical Analysis

The repository implements its security boundary in scripts/run.js. That launcher provides:

  • Package name, version, size, and SHA-512 verification.
  • Sensitive-tier sealing.
  • Per-session or per-call authorization.
  • Per-platform consent bound to the verified package bytes.
  • Argument allow-listing.
  • Audit and transparency records.
  • Symlink rejection and restricted module resolution.

None of those controls apply when the globally installed bws executable is called directly. The documentation therefore creates an alternate execution path around the intended reference monitor.

This is particularly dangerous for authenticated adapters because the underlying package executes JavaScript in an OpenClaw browser session. The issue does not require defeating any launcher gate: the documented command simply avoids the launcher entirely.

Attack Path

  1. A user or ...[truncated 1220 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace every operational bws site ... example with the protected launcher:

    bash
    node scripts/run.js run hn/search "llm" --count 5
    

    or with a verified bws-skill wrapper that unconditionally resolves to scripts/run.js.

  2. Remove direct bws invocations from:

    • The README quick-start section.
    • SKILL installation and usage instructions.
    • Example conversations.
    • Login-state instructions.
    • First-run checklists.
  3. Clearly state that direct use of the upstream binary is unsupported because it bypasses integrity checks, consent gates, and auditing.

  4. If a wrapper executable is distributed, ensure it cannot fall back to the raw upstream executable and add automated documentation tests that reject command examples beginning with bws site.

  5. Consider installing the upstream dependency without exposing its executable globally. A launcher-private installation reduces the likelihood of accidental bypass.

T08 · Insecure Dependencies

Error
Location
SKILL.md:42
Finding

Prominent Installation Instructions Permit Third-Party npm Lifecycle Scripts

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:42-56
Vulnerability Type: Unsafe third-party dependency installation
Risk Level: High

The Skill metadata instructs users to globally install a third-party package without --ignore-scripts, allowing npm lifecycle scripts to execute before the launcher's runtime integrity check can run.

Complete vulnerable code snippet:

yaml
install:
  command: npm install -g browser-web-search@0.4.3
  riskLevel: medium
  riskReason: 通过 npm 全局安装第三方包,该包会在浏览器页面上下文中执行 JavaScript。安装前请审计源码。
  requiresApproval: true
  source:
    registry: npmjs.com
    package: browser-web-search
    repository: https://github.com/sipingme/browser-web-search
    npm: https://www.npmjs.com/package/browser-web-search
  verification:
    - 安装前请审查 GitHub 仓库代码
    - 检查 npm 包的下载量和维护状态
    - 对比 npm 发布版本与 GitHub 源码是否一致
  note: 用户需先通过 npm install -g 全局安装 browser-web-search,运行时调用本地已安装的 bws 命令

The same unsafe command is presented prominently in README.md:8-9 and SKILL.md:214-215. Safer commands using --ignore-scripts appear elsewhere, but those later instructions do not neutralize the unsafe primary installation path.

Technical Analysis

npm packages can define lifecycle hooks such as preinstall, install, and postinstall. These hooks execute during npm install with the privileges of the invoking user. A global installation broadens the affected filesystem scope.

The launcher verifies only the installed package's package.json identity and dist/index.js size and SHA-512 at runtime. That verification occurs after installation and therefore cannot prevent or detect side effects already performed by lifecycle scripts. It also does not verify every file in the package.

Version pinning reduces version drift but does not itself prevent lifecycle execution. The project's own safer documentation recognizes this by recommending --ignore-scripts, making the inconsiste ...[truncated 1362 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace every installation instruction with:

    bash
    npm install -g browser-web-search@0.4.3 --ignore-scripts
    
  2. Update the SKILL frontmatter install.command, README quick start, and all checklists so no conflicting unsafe command remains.

  3. Prefer installation from a locally cached, independently verified tarball:

    • Download the exact tarball.
    • Verify its full npm SRI or SHA-512 value before extraction.
    • Install with lifecycle scripts disabled.
  4. For managed deployments, mirror the audited artifact in an internal immutable registry and restrict npm to that registry.

  5. Verify the complete package artifact, not only dist/index.js, if any other package files can influence module loading or runtime behavior.

  6. Add CI checks that fail when documentation or configuration contains an npm install command for this dependency without --ignore-scripts.

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/run.js:972
Finding

In-Process Third-Party Module Receives Broad Authenticated Browser Authority

Content
View full analysis

Vulnerability Details

File Location: scripts/run.js:972-975 and scripts/run.js:675-680
Vulnerability Type: Excessive authority granted to an in-process dependency
Risk Level: High

After passing launcher checks, the third-party package is imported into the launcher process. The project explicitly acknowledges that the launcher cannot prevent that package from reaching unrelated OpenClaw tabs.

Complete import code snippet:

javascript
process.argv = [process.execPath, bwsEntry, ...cliArgs];

try {
  await import(pathToFileURL(bwsEntry).href);

Complete warning showing the unresolved privilege boundary:

javascript
process.stderr.write(
  `[bws] WARNING: '${adapter}' runs inside your authenticated session. ` +
  `Data flows through the third-party 'browser-web-search' npm package. ` +
  `Launcher cannot prevent the package from reaching other open OpenClaw ` +
  `tabs — close unrelated tabs and use a dedicated browser profile.\n`,
);

Technical Analysis

The SHA-512 gate establishes that the imported entry file matches bytes approved by the launcher authors. It does not sandbox those bytes or limit their runtime authority.

Once imported, the dependency executes in-process and can use the OpenClaw browser automation capability available to it. The documentation states that domain isolation is a design intention rather than a runtime-enforced boundary and that other open tabs may be reachable.

The classification gate controls whether a requested adapter is labeled sensitive. It cannot prove that the imported package will restrict itself to the requested adapter, tab, or domain. Public adapters also cause the same package entry point to be imported without Gates 2-4 because they are classified as public.

Therefore, adapter classification and consent operate as invocation controls, not capability confinement. A compromised dependency, or an audited dependency containing exce ...[truncated 1597 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not load the browser-capable dependency in the launcher process. Run it in a separately confined process or container with:

    • A minimal environment.
    • A dedicated temporary home directory.
    • Restricted filesystem access.
    • Explicit network egress controls.
    • No access to unrelated browser profiles.
  2. Create a dedicated OpenClaw browser profile per trust domain or adapter class. Do not share a profile containing email, banking, enterprise SSO, or unrelated social sessions.

  3. Enforce a single-target-tab policy programmatically rather than relying only on user instructions. The dependency should receive an explicit tab identifier and be denied access to all others.

  4. Enforce domain restrictions at the browser or network layer. Adapter naming and documentation are not security boundaries.

  5. Require explicit browser-capability consent for every import, including nominally public adapters, or provide a separate implementation for public sources that does not receive authenticated browser authority.

  6. Retain package integrity verification, but expand the security model to distinguish code identity from runtime confinement. A valid hash confirms which code runs; it does not establish least privilege.

  7. Use short-lived browser profiles and close or destroy them immediately after sensitive operations.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- file: scripts/run.js

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- file: scripts/run.js

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- file: scripts/run.js

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
中的 `REQUIRED_VERSION` / `ENTRY_SHA512_BASE64` / `ENTRY_EXPECTED_SIZE` 三个常量,并同步 `config.json` 的 `install.verification.integrity` / `capabilities.supplyChain` 字段。

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
中的 `REQUIRED_VERSION` / `ENTRY_SHA512_BASE64` / `ENTRY_EXPECTED_SIZE` 三个常量,并同步 `config.json` 的 `install.verification.integrity` / `capabilities.supplyChain` 字段。

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README advertises broad search and content retrieval across dozens of third-party platforms, but it does not warn users that their queries, account-context requests, and retrieved content may be transmitted to external services. In an agent setting, users may unknowingly send sensitive prompts, research topics, or authenticated-session-derived data to outside platforms, creating privacy, compliance, and data-handling risks.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The primary description forces a specific language/locale for users by presenting the skill overview only in Chinese. The file does not indicate that users may choose another language or that the locale restriction is intentional and justified, which matches the language/locale policy concern.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
71% confidence
Finding

The skill intentionally persists security-relevant state to disk via ~/.bws/audit.log and ~/.bws/consents.json. Even though it claims to store metadata only, those files can reveal which sensitive platforms were accessed, when they were accessed, and operator consent history, which may expose behavioral or account-use patterns on shared systems.

Content

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

md
with identical pkgVersion + entrySha512 reuse the stored consent.
      - name: --dry-run
        purpose: |
          v0.4.10+: run Gates 1-4 + integrity + symlink rejection, write the
          audit record, then exit WITHOUT importing the third-party package.
          Exit 0 = would allow; non-zero = denied (audit log shows reason).
    sensitiveTierGateOrder:

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The README content, headings, operational guidance, and examples are all presented in Chinese, which effectively imposes a single language on users. There is no documented option for other locales or a justification that this skill is intentionally limited to a Chinese-speaking region or audience.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This code emits user-facing installation and safety instructions exclusively in Chinese, including the primary usage guidance and warnings. The policy explicitly disallows forcing a specific language without user opt-in, and there is no indication that this skill is region-specific or that an alternate language is available.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The header says there is 'no subprocess, and no exec sink in this file,' which suggests the file does not execute external code. In reality, the launcher resolves a package path and executes its entrypoint via dynamic import at L0975, which is still code execution even if it is not a shell or subprocess exec. This is an active contradiction in the security-facing documentation, not merely an omission.

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 · scripts/run.js (reported line 437)May include surrounding context.

js
* Sensitivity gate. Four-tier model since v0.4.10 (was three since v0.4.4,
 * was single-tier opt-in before that).
 *
 * Order of precedence (first match wins; all decisions write an audit record):
 *
 *   Gate 1 — BWS_PUBLIC_ONLY=1
 *     Hard isolation. Sensitive adapters are unconditionally denied.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

This code emits the entire help and operational guidance in Chinese, including safety-critical usage, warnings, and environment-variable explanations. Because the file does not offer an alternate language or indicate that the skill is intentionally limited to Chinese-speaking or region-specific users, it imposes a specific locale on all users without opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

SQP-3 applies to all file types and covers language or locale policy violations. The user-facing documentation is written in Chinese throughout, and the file does not indicate that the skill is region-specific or provide an opt-in or alternative language for users in other locales.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This JSON manifest contains all user-facing command descriptions in Chinese only (e.g. lines L025, L030, L035, L040, L045), but does not offer a language option or explain that the skill is intentionally limited to a Chinese-speaking audience. That is a natural-language locale policy concern under the rule for forced language without user opt-in.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.