Back to skill

Security audit

Pagerunner Skill

Security checks for vulnerabilities and agentic risk

Overview

This is a legitimate but very powerful browser automation skill, with disclosed access to real logged-in Chrome sessions and persistence, but it includes unsafe examples and under-scoped handling of credentials, adapters, and scheduled automation.

Install only if you are comfortable giving this MCP server access to real logged-in Chrome profiles. Use a dedicated agent Chrome profile, strict allowed_domains, short retention, and anonymize:true for sensitive pages. Do not put credentials or webhook URLs in shared KV when sealed secrets or a proper secret manager can be used. Avoid the included selector-debug scripts with untrusted selectors, and do not schedule /tmp scripts in cron. Pin and verify the Pagerunner binary before registering it as an MCP server.

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

Error
Location
scripts/debug-selector.sh:17
Finding

JavaScript Injection Through Unescaped CSS Selector Input

Content
View full analysis
[snapshots=5]" exit 1 fi echo "Testing selector stability: $SELECTOR" echo "Snapshots: $SNAPSHOTS" echo "---" for i in $(seq 1 $SNAPSHOTS); do # Get initial count COUNT=$(pagerunner evaluate "$SESSION_ID" "$TAB_ID" "document.querySelectorAll('$SELECTOR').length") ``` ### Technical Analysis Both scripts embed a caller-controlled CSS selector directly inside a single-quoted JavaScript string passed to `pagerunner evaluate`. No JavaScript escaping, JSON serialization, or selector validation is applied. A selector containing a single quote can terminate the intended string literal and introduce additional JavaScript expressions. The resulting code runs in the context of the active browser tab rather than being restricted to a selector lookup. This violates the scripts' documented selector-only trust boundary. In an authenticated tab, injected page-context JavaScript may read visible DOM content, access same-origin storage available to JavaScript, perform authenticated same-origin requests, alter page state, or initiate application actions. HttpOnly cookies would not be directly readable, but the browser may still attach them ...[truncated 1277 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
examples/icp4-daemon-setup.sh:37
Finding

Predictable Shared Temporary Scripts Recommended as Cron Targets

Content
View full analysis
/tmp/agent-a.sh << 'EOF' #!/bin/bash # Agent A: Scrape pricing data and store in KV store SESSION=$(pagerunner open-session --profile agent) TAB=$(pagerunner list-tabs "$SESSION" | jq -r '.[0].target_id') pagerunner navigate "$SESSION" "$TAB" "https://api.example.com/prices" PRICES=$(pagerunner get-content "$SESSION" "$TAB" | jq '.prices') pagerunner kv-set "pricing-pipeline" "latest-prices" "$PRICES" pagerunner kv-set "pricing-pipeline" "last-run" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" echo "Agent A: Stored $(echo "$PRICES" | jq 'length') prices to KV store" pagerunner close-session "$SESSION" EOF ``` ```bash cat > /tmp/agent-b.sh << 'EOF' #!/bin/bash # Agent B: Read prices from KV store, process, and store results SESSION=$(pagerunner open-session --profile agent) TAB=$(pagerunner list-tabs "$SESSION" | jq -r '.[0].target_id') PRICES=$(pagerunner kv-get "pricing-pipeline" "latest-prices") LAST_RUN=$(pagerunner kv-get "pricing-pipeline" "last-run") echo "Agent B: Found $(echo "$PRICES" | jq 'length') prices from run at $LAST_RUN" PROCESSED=$(echo "$PRICES" | jq 'map(select(.price > 1000)) | length') echo "Agent B: Found $PROCESSED high-priced items" pagerunner kv-set "pricing-pipeline" "processed-results" "{\"high_price_count\": $PROCESSED}" pagerunner close-session "$SESSION" EOF ``` ```bash cat > /tmp/agent-c.sh << 'EOF' #!/bin/bash # Agent C: Read all processed data and generate report PRICES=$(pagerunner kv-get "pricing-pipeline" "latest-prices") RESULTS=$(pagerunner kv-get "pricing-pipeline" "processed-results") LAST_RUN=$(pagerunner kv-get "pricing-pipeline" "last-run") cat > report.json << REPORT { "generated_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)", "data_from": "$LAST_RUN", ...[truncated 2854 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
README.md:91
Finding

Unpinned Installation of a High-Privilege Browser Automation Dependency

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
EXAMPLES.md:432
Finding

Unchecked KV-Controlled Webhook Destination Can Exfiltrate Jira Data

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (53)

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · DEBUGGING.md (reported line 307)May include surrounding context.

md
// No warning

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

Adapter registration and execution are especially sensitive because adapter code runs in the user's authenticated browser context and can use inherited credentials to perform privileged actions against sites and APIs. The documentation highlights capability and convenience but lacks an equally prominent warning about the authority delegated to adapter code, making accidental overtrust more likely.

Content

No source excerpt is available for this finding.

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · REFERENCE.md (reported line 1093)May include surrounding context.

"TypeError: ...", source: "https://...", line: 42 }]

text

**Pattern:** Call this after any interaction that should not emit a JS error; treat any `level: "error"` as a hard fail.

---

## Site Intelligence (4 tools) *(v0.5.0+)*

Pagerunner **learns about sites as you use them**. Adapters are short JS functions executed in the browser tab — same origin as the logged-in user, so they inherit all cookies and tokens. The site knowledge store also remembers auth tokens seen in network traffic (in an encrypted vault) and tracks selector health over time.

Seed adapters for **GitHub, Linear, Jira, Notion, and Gmail** are built in — call them without registering anything.

### `get_site_knowledge(origin)`

Return what Pagerunner knows about a site: registered adapters, detected auth tokens (names + detection metadata, never raw values), selector health stats.

```javascript
const k = await get_site_knowledge("https://github.com");
// { adapters: [...], auth_tokens: [{name: "github_pat", d

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SECURITY.md (reported line 251)May include surrounding context.

md
| Provider | Pattern family |
|---|---|
| OpenAI | Classic keys (`sk-...T3BlbkFJ...`), project keys, service-account keys |
| GitLab | Personal access tokens (`glpat-...`) |
| Stripe | Live + test keys (`sk_live_`, `pk_test_`) |
| AWS | Access key IDs (`AKIA...`), secret keys |
| Slack | xapp-1 tokens, bot/user tokens |

Cloud Metadata Access

High
Category
Server-Side Request Forgery
Confidence
90% confidence
Finding

Code accesses a cloud instance metadata endpoint (e.g. 169.254.169.254). A single request can return temporary IAM credentials, making this a high-value SSRF target for credential theft.

Content

Scanner excerpt · SECURITY.md (reported line 499)May include surrounding context.

md
- **Private IPs:** `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`
- **Link-local:** `169.254.0.0/16`
- **File protocol:** `file://`, `javascript:`, `data:`
- **Metadata endpoints:** `http://169.254.169.254` (AWS EC2 metadata)

### Example

Cloud Metadata Access

High
Category
Server-Side Request Forgery
Confidence
90% confidence
Finding

Code accesses a cloud instance metadata endpoint (e.g. 169.254.169.254). A single request can return temporary IAM credentials, making this a high-value SSRF target for credential theft.

Content

Scanner excerpt · SECURITY.md (reported line 507)May include surrounding context.

md
- **Private IPs:** `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`
- **Link-local:** `169.254.0.0/16`
- **File protocol:** `file://`, `javascript:`, `data:`
- **Metadata endpoints:** `http://169.254.169.254` (AWS EC2 metadata)

### Example

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SECURITY.md (reported line 508)May include surrounding context.

md
await navigate(sessionId, tabId, "http://localhost:8000");      // Loopback
await navigate(sessionId, tabId, "http://192.168.1.1:8080");   // Private IP
await navigate(sessionId, tabId, "http://169.254.169.254");    // AWS metadata
await navigate(sessionId, tabId, "file:///etc/passwd");         // File protocol

// ✅ Allowed
await navigate(sessionId, tabId, "https://public-api.example.com");

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The declared description presents a broad, production-oriented Chrome automation capability set, including privacy/security features and advanced session tooling. The supplied code chunk does not implement those features. Instead, it is a narrow example for local frontend verification: it opens a browser session with a personal profile, checks a localhost page, captures a screenshot, and exits. While this is loosely related to Chrome automation, the actual code materially underdelivers relative to the declared purpose and specifically lacks the named capabilities such as PII anonymization, sealed secrets, session checkpoints, site adapters, and video recording.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The code chunk is a usage example for restoring an authenticated browser state and automating Jira access with Pagerunner. It does align partially with the declared idea of authenticated sessions, but it does not implement or demonstrate several prominently declared features: PII anonymization, sealed secrets, site adapters, session checkpoints, or video recording. Instead, the actual behavior centers on snapshot save/restore, unattended session reuse, and optional daemon/KV-store coordination. Because the declared description presents a broader and different feature set than what this code actually does, there is a material description-to-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The declared description emphasizes a browser automation product with features such as authenticated sessions, PII anonymization, sealed secrets, site adapters, session checkpoints, and video recording. The supplied code chunk instead is an infrastructure/demo setup script focused on running a persistent daemon and orchestrating three agents through a shared KV store. Its main behavior is collecting pricing data from an example endpoint, processing it, generating a report, and suggesting cron-based automation. While this is loosely related to automation for agents and uses sessions, the primary purpose and showcased capabilities materially differ from the declared feature set. Several prominent declared features are absent from the code, while the code highlights undeclared capabilities like daemonized multi-agent coordination, KV-based inter-agent communication, and scheduled ETL-style reporting.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The supplied code chunk does not implement or demonstrate the declared headline capabilities such as authenticated sessions, PII anonymization, sealed secrets, site adapters, session checkpoints, or video recording. Instead, it is a diagnostic performance profiling script that measures latency of Pagerunner commands on an existing session/tab. While it is related to browser automation infrastructure, its primary purpose is benchmarking and performance diagnostics, which is materially different from the declared description and is not disclosed there.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents a broad Chrome automation platform with security/privacy and session-management features. The supplied code chunk instead implements a narrow diagnostic script for validating CSS selector stability across repeated snapshots of a page. While selector validation could be a supporting tool within a browser automation system, this specific code does not substantiate the prominent declared capabilities and has a materially different immediate purpose. Therefore, the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

Context Leakage

High
Category
Data Exfiltration
Confidence
85% confidence
Finding

Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Content

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

md
- **I need to handle sensitive data** (PII, credentials, sealed secrets) → [SECURITY.md](SECURITY.md)
- **I want to call a site's API directly from my session** (site adapters) → [REFERENCE.md § Site Intelligence](REFERENCE.md#site-intelligence-4-tools)
- **I want to inspect network / console traffic** → [REFERENCE.md § Network & Console](REFERENCE.md#network--console-2-tools)
- **I want to record the session as a video** → [RECORDING.md](RECORDING.md) (director's guide) or [REFERENCE.md § Video Recording](REFERENCE.md#video-recording-7-tools) for tool signatures
- **Results look wrong? Hallucination?** → [HALLUCINATION_PREVENTION.md](HALLUCINATION_PREVENTION.md)
- **Show me full ICP workflows** → [EXAMPLES.md](EXAMPLES.md)
- **Multi-agent coordination, daemon setup, auto-recovery** → [ADVANCED.md](ADVANCED.md)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly states it works with existing login sessions, cookies, and browser history already loaded, but the manifest text shown here does not present an immediate, prominent privacy warning or consent requirement. That creates a serious risk of unintended access to highly sensitive authenticated data and actions through the user's real browser context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The session persistence/auto-reattach feature preserves authenticated browser state across daemon restarts, but the documentation presents this mainly as resilience and convenience without a prominent warning that cookies, active logins, and tab state remain live. In a multi-agent or shared-host environment, this can lead operators to underestimate how long privileged sessions persist, increasing the chance of unintended reuse, lateral access, or stale authenticated sessions remaining available after expected shutdowns.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The checkpoint and retention guidance documents indefinite snapshot retention by default without clearly warning that checkpoints may contain highly sensitive session artifacts such as authenticated state, cookies, page content, form data, and other PII-bearing browser state. Normalizing indefinite retention in an automation tool substantially increases exposure from disk compromise, over-collection, accidental reuse, and compliance/privacy violations.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The guidance explicitly tells users to store credentials in the KV store, which is a poor default for secrets handling in a browser automation skill that otherwise advertises sealed secrets. KV stores used for coordination are often broadly readable by participating agents, retained for long periods, and not guaranteed to provide secret-specific protections such as encryption-at-rest, scoped access, rotation workflows, or redaction in logs/checkpoints.

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 explicitly instructs contributors to misattribute all commits solely to Stas and to suppress Claude co-authorship, which is a provenance and audit-integrity issue. In an agent skill context, this can conceal AI involvement, reduce accountability, and interfere with forensic review or compliance requirements around authorship disclosure.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
74% confidence
Finding

The snapshot troubleshooting guidance explains how to save and restore session snapshots for an authenticated origin. In a tool designed for real browser automation, snapshot persistence can preserve authenticated state and increase the blast radius if snapshots are reused by unintended parties or stored insecurely.

Content

Scanner excerpt · DEBUGGING.md (reported line 201)May include surrounding context.

const snapshots = await list_snapshots(); console.log(snapshots); // Check if your origin is there

// If missing, create one first await save_snapshot(sessionId, tabId, origin: "https://jira.mycompany.com");

text

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The debugging section normalizes extracting credentials and email values from live page content and form fields during troubleshooting. In a browser automation skill that can operate on authenticated sessions, this expands the chance of sensitive data collection beyond a narrowly justified need and may encourage operators or downstream agents to access secrets as a routine step.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The troubleshooting guidance explicitly discusses recovering visible login credentials, email values, and similar data through get_content and evaluate. Given the skill's authenticated browser context and privacy-oriented positioning, this creates a clear risk of credential harvesting or accidental disclosure by making secret extraction appear operationally normal.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The audit-log examples instruct users to read local logs and directly query session-specific security and PII event data, but provide no warning that these logs may themselves contain highly sensitive metadata. This can lead to unnecessary exposure of local sensitive records, especially in shared environments or when logs are copied into tickets, consoles, or LLM prompts.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

These examples expand the skill from browser automation into generic orchestration of outbound messaging, webhook delivery, and arbitrary API posting. That broadens the blast radius from local browser actions to exfiltration or modification of remote systems, especially when combined with KV-stored credentials, snapshots, and autonomous multi-agent execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The Jira-to-Slack example automates transmission of internal project data to an external service without any explicit warning, confirmation step, or data-classification guidance. In an agent setting, this can normalize silent sharing of sensitive issue titles, blocker details, assignees, and release context outside the source system.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The competitor pipeline example instructs automated posting of scraped and analyzed data into an internal API and database without warning about the consequences of autonomous writes. This creates risk of unauthorized data ingestion, policy violations, or poisoning internal systems if the scraped data is inaccurate, sensitive, or legally restricted.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.