Back to skill

Security audit

weread_assitant

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real WeRead-to-Obsidian helper, but it can use your logged-in browser on arbitrary URLs and overwrite Obsidian notes, so it needs review before installation.

Install only if you are comfortable giving this skill access to a logged-in Chrome debugging session and allowing it to write or overwrite Obsidian notes. Before use, keep remote debugging off except during sync, pass only WeRead URLs, review generated output before publishing, and prefer a test vault or backup until URL allowlisting, publish confirmations, and safer overwrite behavior are added.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/fetch-book.mjs:18
Finding

Authenticated-browser scraping is not restricted to WeRead

Content
View full analysis
{ await sleep(2500); const initial = await evalTarget(targetId, PAGE_EXTRACTOR); const contentBlocks = await collectContent(targetId, Number.isFinite(args.scrolls) ? args.scrolls : 6); const pageInfo = await infoTarget(targetId).catch(() => null); return { capturedAt: new Date().toISOString(), sourceUrl: args.bookUrl, page: { info: pageInfo, title: initial.title, url: initial.url, headings: initial.headings || [], }, ``` From `scripts/fetch-shelf.mjs`: ```js function parseArgs(argv) { const args = { url: DEFAULT_URL, output: DEFAULT_OUTPUT, keepOpen: false, debugDom: false }; for (let index = 0; index < argv.length; index += 1) { const token = argv[index]; if (token === "--url") args.url = argv[index + 1]; if (token === "--output") args.output = argv[index + 1]; if (token === "--keep-open") args.keepOpen = true; if (token === "--debug-dom") args.debugDom = true; } return args; } ``` ```js const data = await withNewTarget( args.url, async (targetId) => { ...[truncated 3198 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/export-obsidian.mjs:308
Finding

Untrusted page content is published as active Markdown without contextual escaping

Content
View full analysis
[!tip] 写法建议", "> 可以直接补三行:", "> 1. 这本书最打动我的观点是什么", "> 2. 它改变了我对什么问题的理解", "> 3. 我接下来准备怎么做", "", "- 暂无读后感,可让 OpenClaw 先帮你起草一版再同步回来。", ]; } return reflections.flatMap((item, index) => [ `### 读后感 ${index + 1}`, "", `- 时间:${item.updatedAt || item.createdAt || "未知"}`, `- 风格:${item.mode || "polished"}`, "", item.content || "", "", ]); } ``` ```js function buildShelfMarkdown(shelf) { const books = shelf.books || []; const lines = books.slice(0, 50).map((book, index) => { const title = book.title || `Untitled ${index + 1}`; const href = book.href || ""; const bookId = book.bookId || "unknown"; return `| ${index + 1} | ${title} | ${bookId} | [打开](${href}) |`; }); ``` ```js function buildBookMarkdown(book, { reflections = [] } = {}) { const metadata = book.metadata || {}; const title = metadata.title || book.page?.title || "Untitled"; const stats = parseReadingStats(book); const currentChapter = pickCurrentChapter(book); const headings = uniqueLines(book.page?.headings || [], 8); const tocLines = uniqueLines((book.toc || []).map((item) => item.title), 20); const quoteCandidates = filterQuoteCandidates(book); const noteLines = uniqueLines(book.notes || [], 12); const contentLines = uniqueLines((book.content?.blocks || []).map((item) => shorten(item, 800)), 10); const themes = inferThemes(book, quoteCandidates); const questionCards = buildQuestionCards(currentChapter, themes, quoteCandidates); const permanentNotes = buildPermanentNoteSeeds({ currentChapter, them ...[truncated 3902 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (19)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/fetch-shelf.mjs

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/fetch-book.mjs --book-url "https://weread.qq.com/..."

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/export-obsidian.mjs --shelf output/weread/shelf.json --book output/weread/books/<slug>.json

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/publish-obsidian.mjs --dir output/obsidian

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/add-book-reflection.mjs --title "书名" --reflection "润色后的读后感" --vault claw_notes

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/add-book-reflection.mjs --title "书名" --reflection "润色后的读后感" --vault claw_notes

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill description is written as an imperative user-facing document entirely in Chinese from the outset, with no indication that other languages are supported or that Chinese is required for a region-specific compliance reason. Under the policy, a skill that effectively constrains interaction to a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The trigger example “把这些感想整理进笔记” is generic language that could apply to many note-editing tasks, not specifically WeRead-to-Obsidian reflection syncing. Because the trigger list does not pair this phrase with explicit exclusions or tighter context requirements, it risks unintended invocation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill explicitly states that Obsidian vault notes are created through obsidian-cli create --overwrite, but the surrounding guidance does not prominently warn that existing notes may be replaced. This creates a realistic risk of unintended data loss or silent modification of user notes, especially because the skill supports automatic sync and republish flows.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The default prompt is broad and conversational enough to encourage invocation from ordinary user phrasing such as wanting to sync a book or polish reflections, which can trigger the skill without explicit user intent. In this skill's context, unintended invocation is more sensitive because it interacts with a logged-in Chrome session and writes content into a local workspace, increasing the chance of unintended access or modification of personal reading data and notes.

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 syncing WeRead data into a local workspace and preparing note-ready material for downstream workflows, which implies local export/formatting. The weread:publish-obsidian script name indicates an additional publication action, suggesting content may be pushed outward rather than only synced locally, which is broader than the stated description.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

After adding a reflection, the script automatically invokes a second script to publish the generated note to Obsidian, creating a side effect beyond the user-visible action of merely updating local reflection data. In this skill’s context, the tool handles local workspace content derived from a logged-in WeRead session, so implicit publication can expose or distribute synced book content and reflections into another system or vault without a separate confirmation boundary.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This module issues network requests to a CDP service via fetch and also exposes browser-control operations, including evalTarget, which transmits supplied expressions to a remote endpoint. The file contains no confirmation prompt, user-facing log/print, or inline warning describing these potentially safety-relevant actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The screenshot helper writes to an arbitrary caller-supplied file path and creates parent directories without validating that the destination stays within an approved workspace. In the context of a skill that syncs browser-derived content into a local workspace using the user's logged-in Chrome session, this can enable unintended file overwrite or placement of sensitive captured page data into unsafe locations if an attacker can influence the path.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This script intentionally uses the user's logged-in browser session to extract potentially sensitive reading data, including visible book text, notes, reading-related metadata, and page content, and then persists it to local disk. In this skill context, that behavior is expected functionality, but it still creates a real privacy and data-handling risk because the capture scope is broad, the content may include copyrighted or personal material, and there is no explicit consent boundary, minimization, or warning at the point of collection.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script extracts authenticated WeRead shelf data, page text snippets, book metadata, and optionally raw DOM-derived candidates, then persists them to a local JSON file without any explicit consent prompt, warning, or minimization. In this skill context, that is security-relevant because it uses the user's logged-in browser session to collect potentially sensitive reading history and visible content, which could later be accessed by other local tools or unintentionally synced elsewhere.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest frames the skill as syncing WeRead shelf state, content, and note-ready Markdown into a local workspace for inspection or preparation. This script's documented purpose and implementation go further by creating or overwriting notes in an Obsidian vault through obsidian-cli, which is a publication step beyond merely preparing/syncing local exports.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The manifest describes syncing WeRead-derived content into a local workspace, but this script delegates publication to an external obsidian-cli binary via execFile. Spawning subprocesses is a materially broader capability than ordinary file transformation/sync logic and is not explicitly justified in the stated purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This script automatically chains shelf fetching, book export, note generation, and publication to Obsidian without any explicit confirmation or dry-run safeguard at the point of execution. In an agent-skill context, that is risky because invoking the skill can cause persistent local file writes and publishing side effects using the user's logged-in browser/session, which may expose reading data or book content to downstream systems unintentionally.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/cdp-client.mjs:3