Back to skill

Security audit

Auto Login

Security checks for vulnerabilities and agentic risk

Overview

This skill is an auto-login/CAPTCHA tool that discloses risky behavior, but it sends and stores full login-page screenshots and can submit forms on arbitrary sites without enough guardrails.

Review carefully before installing. Use only on low-sensitivity sites, configure only a trusted vision API endpoint, assume full page screenshots may leave your machine and remain in ~/.openclaw/workspace, avoid financial/admin/account-recovery pages, and prefer a version that crops only the CAPTCHA, confirms before submit, cleans up screenshots, and keeps Chrome sandboxing enabled.

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

other

Error
Location
index.mjs:111
Finding

Full Login-Page Screenshots Are Transmitted to a Configurable Remote Vision Provider

Content
View full analysis

Vulnerability Details

File Location: index.mjs:111-140, 612-636; recognize.mjs:134-176, 515-520
Vulnerability Type: Excessive sensitive-data disclosure
Risk Level: High

Vulnerable Code

index.mjs:111-140:

js
const imageBuffer = fs.readFileSync(screenshotPath);
const base64Image = imageBuffer.toString('base64');

const response = await fetch(`${config.baseUrl}/chat/completions`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${config.apiKey}`
  },
  body: JSON.stringify({
    model: config.model,
    messages: [
      {
        role: 'user',
        content: [
          {
            type: 'text',
            text: `这是一个网页截图,请识别验证码图片中的文字。
只返回验证码文字本身(通常是 4-6 位字母数字),不要任何其他描述或解释。
如果看不到验证码或无法识别,返回"UNRECOGNIZABLE"。`
          },
          {
            type: 'image_url',
            image_url: { url: `data:image/png;base64,${base64Image}` }
          }
        ]
      }
    ],
    max_tokens: 20,
    temperature: 0.1
  })
});

index.mjs:612-636:

js
screenshots.page = path.join(WORKSPACE_DIR, `${outputPrefix}_page.png`);
await page.screenshot({ path: screenshots.page, fullPage: true });

// ...

screenshots.page = path.join(WORKSPACE_DIR, `${outputPrefix}_page.png`);
await page.screenshot({ path: screenshots.page, fullPage: true });

analysis = await analyzePageWithVision(screenshots.page, config);

recognize.mjs:134-176:

js
export async function recognizeFromBase64(imageBase64, config = {}) {
  const cfg = loadConfig(config);

  const requestBody = {
    model: cfg.model,
    messages: [{
      role: 'user',
      content: [
        { type: 'text', text: '请识别图片中的验证码文字,只返回验证码内容,不要任何其他描述。保持原始大小写,不要转换。' },
        { type: 'image_url', image_url: { url: `data:image/png;base64,${imageBase64}` } }
      ]
    }],
    max_tokens: 100,
    temperature
...[truncated 3196 chars]
Remediation
View remediation

Remediation Suggestions

  1. Identify the CAPTCHA element locally and use an element-level screenshot:
    js
    const captcha = page.locator(captchaSelector).first();
    const imageBuffer = await captcha.screenshot();
    
  2. Never upload a full login page by default. If element detection fails, stop and request an explicit selector rather than silently falling back to a full-page image.
  3. Redact password fields, usernames, payment data, tokens, QR codes, and other sensitive regions before any remote request.
  4. Show the exact destination hostname and require explicit user consent before the first remote upload.
  5. Require HTTPS and validate the endpoint with new URL(). Consider an allowlist for known providers, with a separate explicit opt-in for custom endpoints.
  6. Do not forward a valuable provider credential to an untrusted custom endpoint. Use endpoint-specific credentials and document that bearer tokens are disclosed to the selected provider.
  7. Prefer local OCR when possible and use remote recognition only as an explicit fallback.
  8. Add tests asserting that the outbound image dimensions match the CAPTCHA element rather than the full page.

T09 · Insecure Skill Coding Practices

Warning
Location
index.mjs:392
Finding

Sensitive Full-Page Screenshots Are Persisted Without Access Controls or Cleanup

Content
View full analysis

Vulnerability Details

File Location: index.mjs:396, 612, 630, 652, 684-687; recognize.mjs:515, 546, 566, 589
Vulnerability Type: Insecure storage of sensitive browser data
Risk Level: Medium

Vulnerable Code

index.mjs:392-396:

js
const filledPath = path.join(WORKSPACE_DIR, `${outputPrefix}_filled.png`);
await page.screenshot({ path: filledPath, fullPage: true });

index.mjs:648-652:

js
screenshots.result = path.join(WORKSPACE_DIR, `${outputPrefix}_result.png`);
await page.screenshot({ path: screenshots.result, fullPage: true });
console.log(`✅ 结果截图:${outputPrefix}_result.png`);

index.mjs:682-687:

js
screenshots.error = path.join(WORKSPACE_DIR, `${outputPrefix}_error.png`);
await page.screenshot({
  path: screenshots.error,
  fullPage: true
});

recognize.mjs:542-546:

js
screenshots.filled = path.join(WORKSPACE_DIR, `${outputPrefix}_filled.png`);
await page.screenshot({ path: screenshots.filled, fullPage: true });

recognize.mjs:562-566:

js
screenshots.result = path.join(WORKSPACE_DIR, `${outputPrefix}_result.png`);
await page.screenshot({ path: screenshots.result, fullPage: true });

recognize.mjs:587-589:

js
screenshots.error = path.join(WORKSPACE_DIR, `${outputPrefix}_error.png`);
await page.screenshot({ path: screenshots.error, fullPage: true });

Technical Analysis

The Skill saves complete page screenshots before recognition, after fields have been filled, after submission, and when errors occur. These files are placed in the predictable shared path ~/.openclaw/workspace and are not deleted at the end of execution.

The code does not request restrictive file permissions, establish a retention period, encrypt the files, or make screenshot persistence opt-in. Post-fill and result screenshots are particularly sensitive because they capture the page after automation has modified or submitted ...[truncated 1390 chars]

Remediation
View remediation

Remediation Suggestions

  1. Make screenshot persistence disabled by default and expose it only through an explicit diagnostic option.
  2. Capture only the CAPTCHA element instead of the complete page.
  3. When temporary storage is required, create a private temporary directory with mode 0700 and image files with mode 0600.
  4. Use unpredictable filenames rather than user-controlled or predictable prefixes.
  5. Delete temporary screenshots in a finally block immediately after recognition:
    js
    try {
      // Capture and process the narrowly cropped image.
    } finally {
      await fs.promises.rm(tempDirectory, { recursive: true, force: true });
    }
    
  6. Redact sensitive controls and page regions before saving diagnostic images.
  7. Apply a short, documented retention policy to screenshots that users explicitly elect to keep.
  8. Avoid taking an automatic full-page screenshot on error; save sanitized metadata and logs instead.
  9. Warn users when persistent diagnostic captures are enabled and report the exact output directory.

T09 · Insecure Skill Coding Practices

Warning
Location
index.mjs:594
Finding

Chrome Sandbox Is Disabled While Visiting Arbitrary User-Supplied URLs

Content
View full analysis

Vulnerability Details

File Location: index.mjs:594-599; recognize.mjs:642-646
Vulnerability Type: Unsafe browser execution configuration
Risk Level: Medium

Vulnerable Code

index.mjs:594-599:

js
const browser = await chromium.launch({
  headless: true,
  executablePath,
  args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage']
});

recognize.mjs:642-646:

js
const browser = await chromium.launch({
  headless: true,
  executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
  args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage']
});

The URL loaded into this browser is supplied externally. For example, index.mjs:608 performs:

js
await page.goto(url, { waitUntil: 'networkidle', timeout: 30000 });

Technical Analysis

The --no-sandbox and --disable-setuid-sandbox flags disable important Chrome process-isolation controls. At the same time, the Skill accepts an arbitrary URL and renders the corresponding remote content.

Browser sandboxing is a defense-in-depth boundary intended to limit the effects of renderer compromise. If a target page exploits an unpatched Chrome or rendering-engine vulnerability, disabling this boundary can make it easier for attacker-controlled browser code to reach host resources available to the Chrome process.

The Skill does not need to disable the sandbox to perform ordinary Playwright navigation, screenshots, form filling, or CAPTCHA recognition. These flags therefore weaken host security beyond what is necessary for the declared functionality.

Attack Path

  1. An attacker supplies or recommends a malicious URL to the user.
  2. The Skill launches Chrome with sandbox protections disabled.
  3. Chrome loads and renders attacker-controlled HTML, JavaScript, media, fonts, and other browser content.
  4. The malicious content exploits a browser render ...[truncated 885 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove --no-sandbox and --disable-setuid-sandbox from both browser launch configurations.
  2. Fail safely with a clear setup error if the execution environment cannot support Chrome sandboxing.
  3. Run browser automation under a dedicated, non-privileged operating-system account.
  4. For untrusted URLs, add an additional container or virtual-machine boundary with:
    • no host filesystem mounts;
    • a read-only root filesystem;
    • dropped Linux capabilities;
    • seccomp or equivalent syscall filtering;
    • restricted outbound network access;
    • no access to host credentials or agent configuration.
  5. Keep Chrome and Playwright patched and compatible.
  6. Consider URL policy controls that reject unsupported schemes, local files, loopback targets, and internal network destinations unless explicitly authorized.
  7. Add a security test that inspects launch arguments and fails if sandbox-disabling flags are reintroduced.
Vulnerability Patterns
  • 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (25)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `index.mjs` | Skill 主入口 |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `recognize.mjs` | 验证码识别核心(可复用模块) |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `scripts/run.mjs` | CLI 运行脚本 |

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module sends image data derived from a full-page screenshot to an external vision API, which may expose much more than just the CAPTCHA, including account identifiers or other sensitive page content. In the context of an auto-login skill, this is especially dangerous because users may not realize authentication-related page contents are being transmitted to third-party providers.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill documentation describes capabilities that use environment variables and make outbound network requests to third-party vision APIs, but the manifest does not declare any explicit tool scope or allowed-tools/permissions boundary. This creates a transparency and policy-enforcement gap: users or hosting platforms may not realize the skill can access secrets and transmit page screenshots externally.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The manifest description forces a specific language/locale experience in natural language, and the file does not indicate that users can opt into another language. Under the policy, language constraints should be optional or clearly justified as region-specific.

Content

No source excerpt is available for this finding.

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Content

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

bash
# 正确位置
ls -la ~/.openclaw/workspace/skills/auto-login/

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

The skill explicitly instructs users to send full-page screenshots to external OpenAI-compatible APIs for captcha recognition. In the context of an auto-login skill, those screenshots can include usernames, passwords, session tokens, personal data, or other sensitive page contents, making external transmission materially risky even though the README warns about it.

Content

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

bash
export OPENAI_API_KEY="sk-..."
export OPENAI_BASE_URL="https://api.openai.com/v1"
export OPENAI_MODEL="gpt-4o-mini"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

brew install --cask google-chrome

Linux

sudo apt install google-chrome-stable

text

---

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest and file header describe a general-purpose auto-login skill that fills account credentials, solves CAPTCHAs, and submits login forms. In the implementation, the code takes a screenshot, sends it for CAPTCHA recognition, fills likely CAPTCHA fields, and clicks likely submit buttons, but there is no logic for locating or filling username/password fields or executing configurable multi-site login workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill reads API credentials from a local OpenClaw configuration file automatically, without an explicit consent prompt or clear disclosure that local secrets will be accessed. In this skill's context, that is more dangerous because the same execution also uploads full-page screenshots to a remote vision API, increasing the chance that local credentials and page-sensitive content are used or exfiltrated without informed user approval.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The help text says the skill first uses local Tesseract OCR, falls back to a vision model on low confidence, and only recognizes without submitting in the OCR stage. In actual execution, the local OCR path is skipped entirely in full-screen mode and the code proceeds directly to vision recognition and then auto-fills/submits, so the documentation actively misstates runtime behavior.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The package description frames the skill as a general-purpose web auto-login capability without any narrowing around approved sites, user consent, or safe invocation conditions. In an agent skill ecosystem, overly broad activation language can cause the skill to be invoked in credential-handling contexts it was not explicitly intended for, increasing the risk of misuse, phishing-style automation, or unintended interaction with sensitive login flows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code captures full-page screenshots and writes them to disk in a workspace directory without explicit user disclosure in the CLI flow. Because login pages can contain usernames, QR codes, security prompts, and other sensitive data, this creates a privacy and credential-handling risk through unnecessary local retention.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill automatically fills the inferred CAPTCHA input and clicks a submit/login button without explicit confirmation, increasing the chance of unintended actions on arbitrary sites. In an authentication context, heuristic misidentification can submit forms prematurely, interact with the wrong control, or trigger account lockouts and other side effects.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The CLI mode turns a CAPTCHA-recognition helper into an active browser automation tool that will visit any user-supplied URL, take screenshots, fill inputs, and click submit. That broadens the trust boundary significantly and can cause unintended interaction with arbitrary third-party sites, especially because the automation occurs with minimal validation or user confirmation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The header comment explicitly states the function is automatic login including account, password, and captcha handling. However, the implementation only parses URL/model-related options and calls recognizeCaptcha(options), with no handling of credentials or login submission logic in this file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file presents user-facing help, status, and error messages entirely in Chinese, which imposes a specific language on users without opt-in. This matches the policy category for language or locale violations because no alternative language selection or justification is provided.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest describes a '通用网页自动登录 Skill' with configurable login flows and multi-site rules, but this file's user-facing help text and execution path are centered on captcha recognition only. It invokes recognizeCaptcha(options) and documents OCR/model selection, which is a narrower behavior than the stated auto-login capability.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The natural-language strings in the file, including the header, console output, errors, and help text, are presented in Chinese only. This imposes a language choice on users without offering locale selection or documenting that the skill is intended only for a Chinese-language audience.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The package description is entirely in Chinese, which may impose a language expectation on users without offering a locale choice. Under the language/locale policy, natural-language content should not force a specific language unless it is explicitly optional or justified.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
91% confidence
Finding

The dependency uses a caret range, allowing newer compatible releases to be installed without explicit review. This weakens supply-chain control and can introduce unexpected behavior or newly published malicious/buggy versions into a skill that automates browser login flows and may handle sensitive credentials.

Content

Scanner excerpt · package.json (reported line 21)May include surrounding context.

json
"author": "Lie Troksky and Athena",
  "license": "MIT",
  "dependencies": {
    "playwright-core": "^1.40.0",
    "tesseract.js": "^5.0.0"
  },
  "scripts": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The tesseract.js dependency is also specified with a caret range, which permits unreviewed version drift. Because this skill processes CAPTCHA and login-related content, any dependency compromise or behavioral change could affect credential workflows or leak sensitive page data.

Content

Scanner excerpt · package.json (reported line 22)May include surrounding context.

json
"license": "MIT",
  "dependencies": {
    "playwright-core": "^1.40.0",
    "tesseract.js": "^5.0.0"
  },
  "scripts": {
    "test": "node index.mjs",

Unverifiable Dependency: tesseract.js has 1 known advisory(ies) (GHSA-83rx-c8cr-6j8q (Insecure Default Configuration in tesseract.js)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
84% confidence
Finding

The manifest references tesseract.js without pinning a version even though there is a known advisory associated with the package family, making it impossible to verify from this file whether the deployed version is safe. In a login automation skill, uncertainty around a dependency with a security advisory raises supply-chain risk because OCR components may process sensitive visual content from authentication pages.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The comment at L31 says '使用通用名称,不暴露具体厂商', yet the implementation immediately defines an 'aliyun' provider and hard-codes the DashScope Aliyun endpoint and vendor-specific names. This is an active contradiction between the inline documentation and the code's actual disclosure of provider identity.

Content

No source excerpt is available for this finding.