Back to skill

Security audit

Baoyu Url To Markdown

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its URL-to-Markdown purpose, but it needs review because it can involve authenticated browser sessions, automatically send target URLs to a third-party converter, and persist X/Twitter session cookies in plaintext.

Install only if you are comfortable with a browser automation tool that can process authenticated pages. Avoid using it on private, internal, signed, invitation, password-reset, or token-bearing URLs unless remote fallback is disabled or reviewed. Treat the Chrome profile directory as sensitive, delete any x-session-cookies.json when no longer needed, and avoid --debug-dir on confidential pages because it can save page and network contents.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/lib/extract/html-to-markdown.ts:199
Finding

Automatic Remote Fallback Discloses Complete Target URLs to a Third Party

Content
View full analysis
{ const response = await fetch(buildDefuddleApiUrl(targetUrl), { headers: { accept: "text/markdown,text/plain;q=0.9,*/*;q=0.1", }, redirect: "follow", }); if (!response.ok) { throw new Error(`defuddle.md returned ${response.status} ${response.statusText}`); } const rawMarkdown = (await response.text()).replace(/\r\n/g, "\n").trim(); ``` ```ts // scripts/lib/extract/html-to-markdown.ts:743-747 if (!shouldTryRemoteMarkdownFallback(selectedResult.markdown, cleanedHtml, options)) { return selectedResult; } const remoteDefuddleResult = await tryDefuddleApiConversion(cleanedHtml, url, baseMetadata); ``` ### Technical Analysis Generic Markdown conversion automatically enables a remote extraction fallback whenever the selected outpu ...[truncated 2619 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/lib/browser/cookie-sidecar.ts:54
Finding

X Authentication Cookies Are Automatically Persisted in Plaintext

Content
View full analysis
{ const d = c.domain ?? ""; return d.endsWith("x.com") || d.endsWith("twitter.com"); }, }; ``` ```ts // scripts/lib/browser/cookie-sidecar.ts:54-67 export async function exportCookies( session: TargetSession, config: CookieSidecarConfig, profileDir?: string, ): Promise { const all = await getCookies(session, config.urls); const filtered = config.filterCookie ? all.filter(config.filterCookie) : all; if (!hasRequired(filtered, config.requiredCookieNames)) return false; const filePath = sidecarPath(config.filename, profileDir); await mkdir(dirname(filePath), { recursive: true }); const data: SidecarData = { savedAt: new Date().toISOString(), cookies: filtered }; await writeFile(filePath, JSON.stringify(data, null, 2)); return true; } ``` ```ts // scripts/lib/commands/convert.ts:574-577 } finally { if (adapter?.exportCookies && context) { await adapter.exportCookies(context, runtime.chrome.profileDir).catch(() => {}); } await closeRuntime(runtime); } ``` ### Technical Analysis The X adapter collects cookies for `x.com` and `twitter.com`, including the reusable `auth_token` authentication credential and the `ct0` CSRF token. At the end of processing, the command automatically exports the filtered cookies into `x-session-cookies.json`. The sidecar is serialized as readable JSON without encryption. The `writeFile` operation does not specify a restrictive file ...[truncated 2070 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (36)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a high-level web fetching and page conversion skill. The supplied code instead operates purely on already-available markdown/text/document data, specifically around media link normalization, extraction, and rewriting. While this could be a supporting helper within a larger markdown pipeline, this code chunk itself does not implement the declared skill’s primary behavior or its notable capabilities. Therefore the description does not accurately represent this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This code does not implement the declared primary purpose. Instead of fetching webpages and producing markdown, it provides helper functions for handling media assets (images/videos): determining content type and file extension, normalizing URLs, extracting embedded URLs, sanitizing file name segments, and building output filenames. These behaviors are adjacent support utilities at best, but for media processing rather than webpage-to-markdown conversion. Since the supplied chunk’s actual behavior is materially different from the declared description, this is a mismatch.

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 · scripts/lib/commands/convert.ts (reported line 398)May include surrounding context.

ts
ns.adapter);
    context = {
      input: { url },
      browser: runtime.browser,
      network: runtime.network,
      cdp: runtime.cdp,
      log: logger,
      outputFormat: options.format,
      timeoutMs: options.timeoutMs,
      interactive: runtime.interactive,
      downloadMedia: options.downloadMedia,
    };

    if (adapter.restoreCookies) {
      const restored = await adapter.restoreCookies(context, runtime.chrome.profileDir).catch(() => false);
      if (restored) logger.info(`Restored ${adapter.name} session cookies from sidecar.`);
    }

    if (options.waitMode === "interaction" && adapter.checkLogin) {
      await context.browser.goto(url.toString(), options.timeoutMs).catch(() => {});
      const preLogin = await adapter.checkLogin(context);
      if (preLogin.state !== "logged_in") {
        didLogin = true;
        await waitForInteraction(adapter, context, {
          type: "wait_for_interaction",
          kind: "login",
          provider: preLogin.provider ??

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill explicitly instructs the agent to install dependencies, invoke a browser-based fetcher, read environment-derived paths, and access arbitrary URLs, yet it declares no explicit tool scope or permission boundaries. This increases the chance that an agent runtime will grant broader-than-necessary filesystem, environment, and network access without user-visible constraints.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill encourages fetching arbitrary URLs through Chrome/CDP and supports authenticated/login flows, but it does not prominently warn that visiting a URL may expose browser-identifying data, cookies, or session-authenticated content to remote sites. In practice, users may unknowingly process sensitive internal pages or personal accounts, causing privacy leakage or unintended data retrieval.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
81% confidence
Finding

The skill mandates creation of a persistent EXTEND.md preference file in either the project or user home directory. While not overtly malicious, persistent state can create privacy and cross-context risks: future runs may silently inherit media-download or output-directory behavior, and project-level settings may expose user preferences or cause content to be stored in unintended locations.

Content

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

md
### First-Time Setup ⛔ BLOCKING

When EXTEND.md is not found, you **MUST** use `AskUserQuestion` to gather preferences before creating EXTEND.md. **NEVER** create EXTEND.md with silent defaults. Generation is BLOCKED until setup completes. Batch all three questions into a single call:

- **Q1 — Media** (header "Media"): "How to handle images and videos in pages?"
  - "Ask each time (Recommended)" — Prompt after each save

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This adapter explicitly supports exporting and restoring authenticated X/Twitter session cookies, including required auth cookies such as auth_token and ct0. Persisting reusable session material to disk without an in-file warning, consent flow, or clear disclosure increases the risk of account/session compromise if the profile directory is exposed, reused unexpectedly, or handled by other components.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code calls Network.getCookies for x.com and twitter.com and then extracts authentication-related cookies including auth_token and ct0. This is sensitive credential/session access, but the file contains no confirmation prompt, user-facing log, or explanatory comment/docstring disclosing that behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code cleans Chrome lock artifacts from the profile directory as part of recovery, which is a file-modifying operation that can affect user state. While logger warnings exist, they are not clearly user-facing confirmations, and there is no prompt, comment-level warning, or other disclosure in this file about deleting profile lock files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The code serializes browser cookies, including authentication/session cookies, to a JSON file on disk with no encryption, permission hardening, or user-consent boundary visible in this component. In a URL-fetching skill that explicitly supports login/CAPTCHA workflows, persisted cookies can enable replay of authenticated sessions if the profile directory is accessible to other local users, malware, backups, or logs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The code reads previously saved cookies from disk and injects them back into a live browser session, which can silently re-establish authenticated state. If the sidecar file is stolen or tampered with, this mechanism can facilitate session hijacking or unintended account access, especially because the skill is designed to browse authenticated sites on a user's behalf.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This code records network metadata and potentially sensitive payload data, including request headers, POST data, and later response bodies. The file contains no confirmation prompt, user-facing notice, or explanatory comment/docstring warning that user or system data may be captured during network monitoring.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The call to Network.getResponseBody fetches full response bodies and decodes them into memory, which can include credentials, personal data, or confidential application content. There is no confirmation, warning comment, or other user-visible indication in this file that response contents may be collected.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This function deletes Chrome profile lock artifacts using fs.unlinkSync, which modifies user data on disk. The file contains no confirmation prompt, logging, or user-facing comment/disclosure indicating that lock files will be removed, so the destructive action is silent from the user's perspective.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The debug artifact routine persists full page HTML and a network dump with includeBodies: true, which can capture session tokens, CSRF tokens, Authorization headers, PII, private page content, and responses from authenticated requests. In this skill's context, the browser may be used after manual login/CAPTCHA handling, so debug output can unintentionally store sensitive authenticated data to disk without clear user disclosure or redaction.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code restores session cookies from sidecar/profile storage and later exports cookies back to disk, creating a persistence channel for authenticated sessions. While likely intended to improve usability, storing and reusing cookies for sites like X increases the risk of session theft or cross-user leakage if the profile directory or sidecar storage is exposed, especially in an automation tool that handles logins interactively.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

When enableRemoteMarkdownFallback is set, the code may send the user-supplied target URL to the external service defuddle.md via fetchDefuddleApiMarkdown(). That leaks browsing targets and potentially sensitive query parameters, intranet hostnames, or private document links to a third party without any disclosure or consent mechanism visible in this file, which is especially risky for a URL-fetching skill that may be used on arbitrary user-provided URLs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This function fetches remote media over the network and writes the downloaded bytes to local disk, which are safety-relevant operations under the rule. While failures are logged, there is no visible confirmation prompt, print/log disclosure before performing the actions, or inline comment/docstring warning users that remote content will be downloaded and saved locally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill supports saving markdown, debug artifacts, preferences, and downloaded media to local disk, but the user-facing description does not clearly highlight that this persists potentially sensitive page contents and assets. This can lead to accidental retention of confidential data in project directories, home directories, or debug folders.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

This markdown file directs the agent to "save EXTEND.md" as part of a blocking setup flow, which affects user/project files. Although later sections describe save locations and a confirmation after writing, the setup description does not clearly warn up front that the skill will create directories and write a configuration file as part of first-time use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The code creates a directory on the local filesystem with fs.mkdirSync, which is a file-writing operation. There is no confirmation, logging, or explanatory comment/docstring describing this side effect in this file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code invokes osascript via execFile to bring a browser application to the foreground on macOS. Although this is part of interactive browser control, the file contains no confirmation prompt, log message, or comment clearly warning that it will trigger a local subprocess and change desktop focus.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · scripts/package.json (reported line 12)May include surrounding context.

json
"reader": "bun ./lib/cli.ts"
  },
  "dependencies": {
    "@mozilla/readability": "^0.6.0",
    "chrome-launcher": "^1.2.1",
    "defuddle": "^0.17.0",
    "jsdom": "^29.0.2",

Unverifiable Dependency: @mozilla/readability has 1 known advisory(ies) (CVE-2025-2792 (@mozilla/readability Denial of Service through Regex)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · scripts/package.json (reported line 13)May include surrounding context.

json
},
  "dependencies": {
    "@mozilla/readability": "^0.6.0",
    "chrome-launcher": "^1.2.1",
    "defuddle": "^0.17.0",
    "jsdom": "^29.0.2",
    "remark-gfm": "^4.0.1",

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/lib/browser/profile.ts:29