Back to skill

Security audit

predict-intelligence

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its report-generation purpose, but it needs review because PDF rendering executes mutable third-party JavaScript and setup uses unpinned browser/Python dependencies.

Install only if you are comfortable with the skill making web requests, contacting Polymarket, loading CDN assets during rendering, writing local report files, and running Python/Chromium tooling. Prefer using it in an isolated environment, pin or vendor dependencies and JavaScript assets, and review generated HTML before converting it to PDF.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Warning
Location
templates/report_template.html:326
Finding
Mutable Remote JavaScript Is Retrieved and Executed During PDF Rendering<![CDATA[ ## Vulnerability Details **File Locations**: - `templates/report_template.html:326-330` - `scripts/to_pdf.py:26-35` - `templates/report_template.html:1002` - `templates/report_template.html:1334` - `templates/report_template.html:1368` **Vulnerability Type**: Remote executable content loaded without integrity verification **Risk Level**: Medium ### Vulnerable Code `templates/report_template.html:326-330`: ```html <script src="https://unpkg.com/d3@7/dist/d3.min.js"></script> <!-- TopoJSON: needed for V2 (regional map) and V7 (choropleth). Remove if neither used. --> <script src="https://unpkg.com/topojson-client@3/dist/topojson-client.min.js"></script> <!-- d3-sankey: ONLY needed for V8 (Sankey). Remove if not used. --> <script src="https://unpkg.com/d3-sankey@0.12.3/dist/d3-sankey.min.js"></script> ``` `scripts/to_pdf.py:26-35`: ```python with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page(viewport={"width": 860, "height": 1200}) page.goto(f"file://{abs_html}", wait_until="networkidle", timeout=timeout * 1000) page.wait_for_timeout(5000) page.pdf( path=pdf_path, format="A4", print_background=True, margin={"top": "0", "right": "0", "bottom": "0", "left": "0"}, ) ``` The template also retrieves remote map data during rendering: ```javascript d3.json('https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json').then(function(world){ ``` ```javascript d3.json('https://cdn.jsdelivr.net/npm/us-atlas@3/states-10m.json').then(function(us){ ``` ### Technical Analysis The generated report imports JavaScript directly from third-party CDNs. Several URLs use mutable major-version selectors such as `d3@7`, `topojson-client@3`, and `world-atlas@2`. None of the script elements include Subresource Integrity hashes. The PDF converter opens the HTML in Chromium and allows the imported scripts to execute. Consequently, the effective code executed during report generation ...[truncated 2186 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Vendor D3, TopoJSON, d3-sankey, fonts, and atlas datasets inside the project. 2. Modify the template to reference local, reviewed files and render reports with network access disabled. 3. If CDN use is unavoidable: - Pin exact immutable versions instead of major-version selectors. - Add verified `integrity` and `crossorigin="anonymous"` attributes to every external script. - Use a restrictive Content Security Policy that permits only explicitly required origins. 4. Intercept Playwright requests and reject all origins not on a narrow allowlist. 5. Prefer an offline browser context after all required assets have been packaged locally. 6. Keep Playwright and Chromium on a tested, security-supported release and verify downloaded browser binaries. 7. Validate remote JSON structures, enforce response-size limits, and fail closed when integrity or schema checks fail. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding
Python and Browser Dependencies Are Installed Without Reproducible Version or Hash Pinning<![CDATA[ ## Vulnerability Details **File Locations**: - `SKILL.md:37-40` - `README.md:45-47` - `scripts/requirements.txt:1-5` **Vulnerability Type**: Unpinned third-party dependency installation **Risk Level**: Medium ### Vulnerable Code `SKILL.md:37-40`: ```bash pip install playwright playwright install chromium ``` `README.md:45-47`: ```bash pip install playwright && playwright install chromium ``` `scripts/requirements.txt:1-5`: ```text jinja2>=3.1 requests>=2.31 staticmap>=0.5.7 Pillow>=10.0 playwright>=1.40 ``` ### Technical Analysis The documented setup installs the latest Playwright release available at execution time and then downloads a corresponding Chromium binary. The requirements file specifies only lower bounds, permitting future versions of every dependency. There is no lock file, exact version constraint, package hash, browser-binary checksum, or documented trusted package index. This prevents reproducible installation and allows code not present during the audit to enter the execution environment later. Python package installation can execute package build or installation logic under the privileges of the user running `pip`. Playwright’s browser installer also downloads and installs a substantial executable component. These actions are necessary in principle for the declared PDF-generation feature, but unrestricted future-version installation exceeds the minimum necessary supply-chain trust. No evidence was found that the named packages are typographical imitations or currently malicious. The vulnerability is the absence of controls against future compromise, unexpected dependency resolution, or malicious artifacts delivered through an untrusted package source. ### Attack Path 1. An attacker compromises a permitted package release, dependency account, package index, or browser-download channel. 2. The attacker publishes a malicious version that satisfies an unconstrained instruction such as `pip install playwright` or a lower-bou ...[truncated 1286 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace lower-bound constraints with exact, tested versions. 2. Generate a reproducible lock file containing hashes for every direct and transitive dependency. 3. Install with hash enforcement, for example through a locked requirements file and `pip install --require-hashes`. 4. Pin the Playwright version together with its compatible Chromium revision. 5. Verify browser binaries using trusted checksums or signed release metadata. 6. Configure an explicit trusted package index and prohibit fallback to unexpected indexes. 7. Install dependencies in an isolated virtual environment under an unprivileged account. 8. Avoid running `pip` or the Playwright browser installer as root or an administrator. 9. Remove unused legacy dependencies from `scripts/requirements.txt` to reduce the supply-chain attack surface. 10. Add automated dependency auditing and controlled update review before changing any pinned version. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared description presents this as an intelligence prediction skill that answers forecasting questions and produces probability-ranked predictive reports with Polymarket signals. The supplied code chunk does not implement forecasting, outcome analysis, market data access, or any prediction-related computation. Instead, it is purely a presentation/export tool: it reads JSON input, renders a Jinja2 template, writes HTML, and optionally prints it to PDF with Playwright. While PDF generation and support for client-side visualizations are consistent with part of the description, the core claimed capability—predictive intelligence—is absent from this code. Therefore, this code chunk materially underdelivers relative to the declared primary purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description presents a comprehensive prediction skill that can answer forecasting questions and produce polished reports with visualizations and consensus signals. The supplied code chunk is much narrower: it only searches Polymarket events/markets for a user query, extracts market probabilities/options, and returns formatted JSON. Using Polymarket as a consensus source is consistent with part of the description, but the main claimed capabilities—prediction generation, broad outcome analysis, PDF report creation, and D3 visualizations—are absent. This is a material description-to-behavior mismatch rather than a minor implementation detail.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description presents this skill as an intelligence/prediction system that answers forecasting questions and produces analytical reports. However, the supplied code does not perform any prediction, data retrieval, analysis, ranking, visualization generation, or Polymarket integration. Its sole function is converting an existing local HTML file into a PDF via a browser renderer. While PDF generation is mentioned in the description, this code only covers a narrow implementation detail and not the skill's stated primary purpose. Therefore the description materially misrepresents the actual behavior of the provided code chunk.

Hidden Instructions

High
Category
Prompt Injection
Content
</div>
  </header>

  <!-- VISUALIZATION — right after verdict, before analysis -->
  
  <section class="viz-section">
    <h2>Theater Overview</h2>
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
<!--
  ══════════════════════════════════════════════════════════════════
  PREDICT INTELLIGENCE REPORT — HTML TEMPLATE
  ══════════════════════════════════════════════════════════════════
Confidence
95% confidence
Finding
The template embeds extensive hidden instructions in HTML comments that are directed at an AI agent, including strong behavioral constraints like copying code verbatim and following exact structure. In an agentic workflow, such embedded prompt-like instructions are untrusted input and can override or bias higher-level system behavior, creating prompt injection risk even if the current content is not overtly malicious.

Hidden Instructions

High
Category
Prompt Injection
Content
</style>
<!-- ═══════════════════ END CSS ═══════════════════ -->

<!-- D3 is required for ALL viz types. Always include. -->
<script src="https://unpkg.com/d3@7/dist/d3.min.js"></script>
<!-- TopoJSON: needed for V2 (regional map) and V7 (choropleth). Remove if neither used. -->
<script src="https://unpkg.com/topojson-client@3/dist/topojson-client.min.js"></script>
Confidence
93% confidence
Finding
The inline comments around external script inclusion are hidden instructions that tell an agent what dependencies to load or keep. In an agent setting, this can manipulate runtime behavior and increase exposure to external resources, especially when the instructions come from the file being processed rather than a trusted controller.

Hidden Instructions

High
Category
Prompt Injection
Content
<span class="outcome-tag">MOST LIKELY</span>
    </div>

    <!-- Remaining outcomes — no "top" class, no tag -->
    <div class="outcome no-break">
      <span class="outcome-pct">28.0%</span>
      <div class="outcome-bar">
Confidence
88% confidence
Finding
These hidden instructions are lower risk than execution-oriented ones, but they still represent untrusted prompt content telling an agent how to structure output. In a skill intended for autonomous report generation, such instructions can steer model behavior in ways not intended by the operator.

Hidden Instructions

High
Category
Prompt Injection
Content
})();
</script>

<!-- ── [V3] ENTITY GRAPH — force-directed network ─────────────
     AGENT DATA: Replace "raw" object.
     nodes[]: {"id","label"(≤16 chars),"type"} — max 8 nodes
     edges[]: {"from","to","label"(≤14 chars),"type"}
Confidence
93% confidence
Finding
The hidden instructions embedded near the visualization script tell the agent exactly what data to replace and imply that surrounding code should be preserved. In an agent pipeline, this is dangerous because untrusted file content can influence transformation logic and preserve potentially unsafe code patterns or external dependencies.

Hidden Instructions

High
Category
Prompt Injection
Content
})();
</script>

<!-- ── [V5] COMPARISON BARS — horizontal ranked bars ──────────
     AGENT DATA: Replace "barConfig" object.
       unit:   suffix for values (e.g. "$B", "%", "K troops")
       bars[]: {label(≤18), value(number)} — max 8, auto-sorted desc
Confidence
93% confidence
Finding
This hidden instruction similarly attempts to control how an agent populates the comparison-bars visualization. While not directly malicious, it is still prompt injection surface because an untrusted file is instructing an autonomous system how to behave and what to preserve.

Hidden Instructions

High
Category
Prompt Injection
Content
})();
</script>

<!-- ── [V8] SANKEY — flow diagram (funding, resources, influence) ──
     AGENT DATA: Replace "sankeyConfig" object.
       nodes[]: {name(≤18)} — max 12 nodes
       links[]: {source(index), target(index), value(number)} — max 15 links
Confidence
94% confidence
Finding
The Sankey section contains hidden agent instructions embedded alongside code, which expands the prompt injection surface in a file likely to be consumed by an automated agent. Because this skill is explicitly for AI-generated reports, embedded instructions are more dangerous here than in a static human-only template.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README explicitly advertises autonomous web research, live market fetching, file generation, and shell-command capability, but it does not warn users that the skill may transmit prompts or derived data to external services, write local files, or invoke system-level tooling. In an agentic environment, this omission can lead to unintended privacy exposure, network egress, and local system side effects because operators may enable the skill without understanding its permissions and behavior.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill explicitly requires web search, URL fetch, file read/write, and shell execution, but it does not declare any tool scope or permission boundaries. In an agentic environment, this can cause the skill to run with broader-than-necessary capabilities, increasing the risk of unintended network access, file modification, or command execution when invoked on untrusted inputs.

Vague Triggers

Medium
Confidence
87% confidence
Finding
The catch-all phrasing such as coverage of 'any predicting question' makes the skill eligible for a very wide set of prompts, which is dangerous given its required access to web, files, and shell commands. Overbroad routing expands the attack surface by making it easier for unrelated or adversarial prompts to invoke a privileged workflow.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The invocation guidance is extremely broad, covering generic phrases like 'will X happen' and outcome analysis across virtually any domain. In systems that auto-select skills from natural-language descriptions, this can cause over-triggering, leading the skill to gain access to network, file, and shell capabilities in situations where a narrower or safer skill should have been used.

Missing User Warnings

Low
Confidence
82% confidence
Finding
This code performs outbound HTTP requests to Polymarket's API as part of fetching market data, which involves transmitting user-supplied search intent derived from the query. Although network access is central to the script's purpose, the file itself provides only a generic description and does not clearly warn the user that external API calls will be made.

Missing User Warnings

Low
Confidence
87% confidence
Finding
The script writes JSON output to a path provided via --output, but there is no confirmation prompt or explicit warning that a local file will be created or overwritten. For a code file, file-write operations should have some visible disclosure unless the behavior is clearly communicated.

Unpinned Dependencies

Low
Category
Supply Chain
Content
jinja2>=3.1
requests>=2.31
staticmap>=0.5.7
Pillow>=10.0
Confidence
94% confidence
Finding
The dependency is specified with a lower-bound version only, which makes builds non-reproducible and can lead to installation of different releases over time. In a skill that renders reports and may process templates, leaving Jinja2 unpinned also makes it harder to ensure the deployed version is not one of the releases affected by known security issues.

Unverifiable Dependency: jinja2 has 16 known advisory(ies) (CVE-2019-10906 (Jinja2 sandbox escape via string formatting); CVE-2014-1402 (Incorrect Privilege Assignment in Jinja2); CVE-2025-27516 (Jinja2 vulnerable to sandbox breakout through attr filter selecting format metho) +13 more), 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.

Unpinned Dependencies

Low
Category
Supply Chain
Content
jinja2>=3.1
requests>=2.31
staticmap>=0.5.7
Pillow>=10.0
playwright>=1.40
Confidence
93% confidence
Finding
Using requests>=2.31 allows future versions to be installed implicitly, reducing reproducibility and making security posture unpredictable across environments. Because this skill likely performs network access for prediction inputs or consensus signals, an unpinned HTTP client increases the chance of silently inheriting a vulnerable or behavior-changing release.

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), 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.

Unpinned Dependencies

Low
Category
Supply Chain
Content
jinja2>=3.1
requests>=2.31
staticmap>=0.5.7
Pillow>=10.0
playwright>=1.40
Confidence
88% confidence
Finding
The staticmap package is also unpinned, so installations may resolve to different versions over time. Even without a cited advisory here, non-deterministic dependency resolution creates supply-chain and stability risk, especially in report-generation workflows.

Unpinned Dependencies

Low
Category
Supply Chain
Content
jinja2>=3.1
requests>=2.31
staticmap>=0.5.7
Pillow>=10.0
playwright>=1.40
Confidence
94% confidence
Finding
Pillow>=10.0 does not guarantee a specific secure release and may permit vulnerable or incompatible versions depending on the resolver and environment. Since this skill generates PDFs and likely handles images, image-parsing libraries are security-sensitive and historically exposed to memory corruption and resource-consumption issues.

Unverifiable Dependency: Pillow has 16 known advisory(ies) (CVE-2016-2533 (Pillow buffer overflow in ImagingPcdDecode); CVE-2023-50447 (Arbitrary Code Execution in Pillow); CVE-2021-27922 (Pillow Uncontrolled Resource Consumption) +13 more), 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.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31
staticmap>=0.5.7
Pillow>=10.0
playwright>=1.40
Confidence
90% confidence
Finding
An unpinned Playwright version makes browser automation behavior and security fixes unpredictable across deployments. Because browser automation can fetch and render remote content, deterministic version control is important to reduce exposure to newly introduced regressions or known flaws.

Intent-Code Divergence

Low
Confidence
94% confidence
Finding
The template header instructs agents to pick 1 or 2 visualization types and delete all unused sections, but the file actually includes sections for V1, V2, V3, V4, V5, V7, V8, V9, and V10 simultaneously. This is an active contradiction between the embedded documentation and the shipped template content, not merely incomplete documentation.

Static analysis

No suspicious patterns detected.