Back to skill

Security audit

Non-Annoying News

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent personal news digest skill with clear user-consent gates, though its optional HTML renderer should be treated carefully with untrusted content.

Before installing, expect the skill to ask setup questions and only allow browser, X/Twitter, mailbox, delivery, or scheduling access when you explicitly want those sources or actions. Do not render arbitrary or untrusted HTML with the bundled renderer unless it is sanitized or run with network and JavaScript disabled; use reviewed, pinned renderer dependencies where possible.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/render_issue.mjs:27
Finding

Unrestricted Active Content and Network Access During HTML Rendering

Content
View full analysis

Vulnerability Details

File Location: scripts/render_issue.mjs, lines 27–30
Vulnerability Type: Browser-based active-content execution with unrestricted outbound requests
Risk Level: Medium

javascript
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage({ viewport: { width: 794, height: 1123 }, deviceScaleFactor: 1 });
await page.goto('file://' + input, { waitUntil: 'networkidle' });

const pdfPath = path.join(outDir, `${base}.pdf`);

Technical Analysis

The renderer opens a caller-selected local HTML file in Playwright Chromium with JavaScript enabled by default. It does not create a restricted browser context, intercept requests, enforce an outbound-domain allowlist, or reject active elements such as scripts and iframes.

Consequently, HTML supplied to the renderer can execute JavaScript and initiate requests to arbitrary external origins. Remote stylesheets, images, fonts, scripts, frames, and other resources can also be loaded automatically. This network capability is not necessary for rendering a self-contained local document and therefore exceeds least privilege.

Chromium's browser sandbox and same-origin policy reduce direct host-file access, so this does not by itself establish arbitrary host compromise or access to unrelated local files. Nevertheless, malicious HTML can transmit information already embedded in or exposed to the rendered document, contact tracking endpoints, consume network or processing resources, and manipulate the generated PDF and screenshots at render time.

Attack Path

  1. An attacker-controlled article, template, imported file, or generated issue introduces a script or remote resource into an issue HTML file.
  2. The user or agent invokes scripts/render_issue.mjs with that file as the input.
  3. Playwright starts Chromium and navigates to the local HTML document.
  4. Embedded JavaScript executes, or the browser automatica ...[truncated 978 chars]
Remediation
View remediation

Remediation Suggestions

  1. Create an isolated browser context with JavaScript disabled by default:
    javascript
    const context = await browser.newContext({ javaScriptEnabled: false });
    const page = await context.newPage();
    
  2. Intercept every request and permit only resources required for local rendering, such as approved file: and data: URLs:
    javascript
    await page.route('**/*', async route => {
      const url = new URL(route.request().url());
      if (url.protocol === 'file:' || url.protocol === 'data:') {
        await route.continue();
      } else {
        await route.abort();
      }
    });
    
  3. Sanitize HTML before rendering. Reject or remove scripts, iframes, event-handler attributes, form submissions, and remote resource URLs.
  4. Make network-enabled rendering an explicit opt-in and require a user-approved host allowlist.
  5. Prefer self-contained documents with local CSS, embedded fonts, and validated local images.
  6. Apply rendering timeouts and resource limits to reduce denial-of-service risk.
  7. Document that only trusted or sanitized HTML may be passed to the renderer.

T08 · Insecure Dependencies

Note
Location
scripts/render_issue.mjs:8
Finding

Unpinned Third-Party Renderer Installation Guidance

Content
View full analysis

Vulnerability Details

File Location: scripts/render_issue.mjs, lines 8–14
Vulnerability Type: Mutable and unpinned npm dependency installation
Risk Level: Low

javascript
try { chromium = require('playwright').chromium; }
catch (_) {
  try { chromium = require('playwright-chromium').chromium; }
  catch (err) {
    console.error('Missing renderer dependency. Install one of: npm install playwright OR npm install playwright-chromium');
    process.exit(2);
  }
}

Related guidance in references/layout-and-render-qa.md, line 22, also advises using Playwright or Chromium when installable without specifying a reviewed version or lockfile.

Technical Analysis

The renderer recommends installing playwright or playwright-chromium through an unconstrained npm install command. The project does not provide a reviewed package.json, exact version constraint, lockfile, integrity record, or controlled installation procedure.

The referenced package names are established npm packages, and the audit found no evidence that they are intentionally malicious. The risk arises because an unpinned installation resolves whatever package and transitive dependency versions are current at installation time. npm packages may execute lifecycle scripts during installation and application code when imported.

This creates a mutable supply-chain boundary: future dependency changes, registry compromise, account compromise, or an unexpected transitive dependency can alter code executed in the user's environment without any corresponding change to this project.

Attack Path

  1. The user runs the renderer without either supported package installed.
  2. The script displays the suggested unpinned npm install command.
  3. The user follows the instruction.
  4. npm resolves current package and transitive dependency versions from the configured registry.
  5. Package lifecycle scripts may execute during installation. 6 ...[truncated 810 chars]
Remediation
View remediation

Remediation Suggestions

  1. Add a reviewed package.json that declares an exact Playwright version.
  2. Commit the corresponding lockfile and install dependencies with npm ci rather than unconstrained npm install.
  3. Document the expected npm registry and avoid alternative or untrusted package sources.
  4. Review dependency updates before regenerating the lockfile.
  5. Use automated dependency and integrity scanning in release workflows.
  6. Where operationally compatible, suppress unnecessary lifecycle scripts during installation and explicitly perform only the required browser installation step.
  7. Replace the current message with a pinned installation procedure tied to the reviewed project manifest.
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 Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear description-behavior mismatch. The declared purpose describes a broad personal newspaper/news digest product with onboarding, configuration, source ingestion, rendering, and editorial/release workflows. The actual code only implements a small QA utility that scans provided files for specific regex matches and reports failures. While editorial QA is mentioned in the description, this code does not represent the overall declared capability and instead has a materially different primary purpose as a text lint/check script. No evidence appears of digest creation, source handling, scheduling, personalization, or rendering.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/render_issue.mjs`: render HTML to PDF and PNG previews with Playwright when available.

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
55% 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 · references/editorial-standard.md (reported line 52)May include surrounding context.

md
- Do not write about the source as a post unless that is the news. Write about the subject.
- Avoid generic labels: "interesting", "potentially relevant", "worth watching", "food for thought".
- Use strong nouns and verbs. Replace vague abstractions with specific mechanisms, numbers, names, and consequences.
- Do not apologize inside the issue for source limitations. State boundaries cleanly in source notes or copy.

## Article anatomy

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

This is a manifest-style JSON file, so vague-trigger review applies. The note says to complete the Personalization Gate before generating a personal issue or scheduling a recurring job, but it does not define the actual trigger phrases, invocation conditions, or exclusion cases for when those actions occur.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · references/source-adapters.md (reported line 34)May include surrounding context.

md
- Newsletter/mailbox search via configured mail tools.
- Team/chat delivery tools when explicitly requested and configured.

Never ask the user to paste tokens, cookies, or secrets into chat.

## X/Twitter bookmarks

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script opens attacker-controlled or untrusted local HTML in a real Chromium instance and waits for the page to load fully, which allows that HTML to initiate outbound network requests, load remote subresources, and potentially leak local document contents or tracking data during rendering. In this skill's context, issues are explicitly assembled from many external and user-provided sources, so rendering without network restrictions or disclosure increases the chance of SSRF-like fetches, privacy leakage, and unintended contact with attacker infrastructure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
72% confidence
Finding

Natural-language policy review applies to all file types. The presence of a configurable "newspaper.language" field alone does not show a violation, but the file does not state that language selection is user-chosen or optional, which can create ambiguity around whether output language may be forced.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The field note for newspaper.language states only 'output language' and does not explicitly require that the language be selected by or offered to the user. Under the policy, locale or language constraints should be user-chosen or clearly documented as justified; this wording leaves room for the skill to impose a language without opt-in.

Content

No source excerpt is available for this finding.