Back to skill

Security audit

webvoyager

Security checks for vulnerabilities and agentic risk

Overview

This web-automation skill is coherent but grants broad browser action and page-data handling authority without enough user control or safety boundaries.

Install only if you are comfortable giving the agent broad browser-automation authority. Use it with a fresh, minimally privileged browser profile, avoid authenticated or sensitive sites unless explicitly intended, require manual approval before submissions, purchases, posts, account changes, credential entry, or sensitive extraction, and restrict allowed domains and vision backends where possible.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
references/examples.md:128
Finding

Untrusted Webpage Content Can Control Privileged Browser Actions

Content
View full analysis
{ // Prepare context for vision model const prompt = this.buildReasoningPrompt(task, state, history); // Send annotated screenshot and prompt to vision model const response = await this.visionModel.analyze({ image: state.annotatedScreenshot, prompt, systemPrompt: this.getSystemPrompt(), }); // Parse action from response return this.parseAction(response, state); } private buildReasoningPrompt( task: WebTask, state: AnnotatedPageState, history: StepHistory[] ): string { let prompt = `## Task ${task.instruction} ## Current Page URL: ${this.page.url()} Title: ${await this.page.title()} ## Interactive Elements (marked on screenshot) `; for (const mark of state.marks) { prompt += `[${mark.id}] ${mark.element.type}: "${mark.element.label}" `; if (mark.element.attributes['href']) { prompt += `(href: ${mark.element.attributes['href']})`; } prompt += '\n'; } if (history.length > 0) { prompt += '\n## Previous Actions\n'; for (const step of history.slice(-5)) { prompt += `Step ${step.step}: ${step.action.type}`; if (step.action.target) prompt += ` on "${step.action.target}"`; if (step.action.value) prompt += ` with value "${step.action.value}"`; prompt += ` - ${step.result.success ? 'Success' : 'Failed'}\n`; } } prompt += ` ## Instructions 1. Look at the annotated screenshot 2. Identify which element to interact with based on the task 3. Choose the appropriate action type 4. Provide your reasoning ## Response Format { "reasoning": "explanation of why this action", "action": { "type": "clic ...[truncated 2858 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
references/examples.md:257
Finding

Unrestricted Browser Navigation Permits Access to Internal Resources

Content
View full analysis
{ await this.initialize(); await this.page.goto(task.startUrl); const history: StepHistory[] = []; let stepCount = 0; let taskCompleted = false; ``` Model-selected navigation is also unrestricted: ```typescript private async executeNavigate(action: Action): Promise { await this.page.goto(action.value || ''); await this.page.waitForLoadState('networkidle'); return { success: true }; } ``` ### Technical Analysis Both `task.startUrl` and the value of a generated `navigate` action are passed directly to Playwright's `page.goto`. The implementation does not validate the URL scheme, destination hostname, resolved IP address, port, or redirect chain. Consequently, navigation may target loopback interfaces, private network ranges, link-local addresses, cloud metadata services, or other resources reachable from the agent's runtime but unavailable to an external attacker. The page-state capture process can then collect screenshots, HTML, accessibility information, and interactive elements from the reached resource. This is an SSRF-like trust-boundary violation implemented through a headless browser. It can be initiated directly through a crafted task URL or indirectly through model manipulation. ### Attack Path 1. An attacker supplies a task whose `startUrl` references an internal service, or causes the model to generate a `navigate` action through malicious page content. 2. `page.goto` requests the supplied URL from the network context of the agent host. 3. The destination resolves to a loopback, private, link-local, metadata, or otherwise restricted endpoint. ...[truncated 1024 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
references/examples.md:322
Finding

Full Page Data Is Transmitted to a Vision Backend Without Redaction Controls

Content
View full analysis
{ const screenshot = await this.page.screenshot({ type: 'png' }); const html = await this.page.content(); const accessibilityTree = await this.getAccessibilityTree(); const interactiveElements = await this.findInteractiveElements(); return { screenshot, html, accessibilityTree, interactiveElements, }; } ``` The annotated screenshot and page-derived prompt are transmitted to the configured vision model: ```typescript const response = await this.visionModel.analyze({ image: state.annotatedScreenshot, prompt, systemPrompt: this.getSystemPrompt(), }); ``` Task-completion checks transmit the screenshot again: ```typescript const response = await this.visionModel.analyze({ image: state.annotatedScreenshot, prompt, }); ``` ### Technical Analysis The browser state capture includes a full-page screenshot, complete HTML, accessibility data, and metadata for interactive elements. The screenshot and page-derived prompt are then submitted to a configurable vision backend. There is no demonstrated filtering of password fields, authentication tokens, personal information, financial data, private messages, or other protected content. The example also does not establish user consent, data-minimization rules, provider allowlisting, retention restrictions, or a prohibition against processing sensitive pages. Although the shown model calls explicitly transmit the screenshot and prompt rather than the stored `html` field, the prompt contains page-derived element labels, URLs, and action history. The retained state also increases exposure if histories or results are logge ...[truncated 1384 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · references/examples.md (reported line 230)May include surrounding context.

md
}
}`;

    return prompt;
  }

  private getSystemPrompt(): string {

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill advertises autonomous web navigation, form submission, cross-site workflows, and data extraction but does not include user-facing warnings or guardrails about consent, destructive actions, sensitive data handling, or site policy compliance. In this context, the omission matters because the skill is specifically designed to perform real browser actions that can cause unintended submissions, privacy violations, or unauthorized automation if invoked without explicit confirmation boundaries.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The example sends annotated screenshots to an external vision model and builds prompts from live page context, but the sample does not include any consent, redaction, or data-classification controls. In a web automation agent, screenshots can contain credentials, personal data, internal dashboards, or payment details, so transmitting them off-box can leak sensitive information to third-party services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The page-state capture collects full screenshots, complete HTML, and accessibility-tree data, which is a broad sweep of potentially sensitive content from the current browser session. Even if not all of it is immediately exfiltrated in this snippet, this design materially increases exposure because downstream logging, model submission, storage, or history retention could disclose secrets, tokens, PII, or protected business data.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.prompt_injection_instructions

Prompt-injection style instruction pattern detected.

Warn
Code
suspicious.prompt_injection_instructions
Location
references/examples.md:173