Back to skill

Security audit

financial-report-analyzer-pro

Security checks for vulnerabilities and agentic risk

Overview

The package does not show malware-like behavior, but it substantially overstates financial-report parsing and analysis capabilities in a way that could mislead users.

Install only if you understand this appears to be a limited demo for normalized JSON, not the full PDF/XBRL/Excel financial-report analyzer described. Do not rely on its output for investment, audit, or business decisions without independently checking the source filing and the generated report, especially for non-JSON inputs or reports from untrusted parties.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/render_report.py:6
Finding
Unescaped Markdown and HTML Content Injection in Report Rendering<![CDATA[ ## Vulnerability Details **File Location**: `scripts/render_report.py`, lines 6-29 **Vulnerability Type**: Unescaped attacker-controlled content in Markdown output **Risk Level**: Medium ### Vulnerable Code ```python def render(result: dict) -> str: lines = ["# Financial Report Analysis", ""] comp = result.get("company") or {} period = result.get("period") or {} lines.append(f"**Company:** {comp.get('name','?')} ") lines.append(f"**Period:** FY{period.get('fiscal_year','?')} ({period.get('reporting_basis','?')})") lines.append("") if "executive_summary" in result: lines.append("## Executive Summary"); lines.append(""); lines.append(result["executive_summary"]); lines.append("") if "ratios" in result: lines.append("## Key Ratios"); lines.append("") for group, vals in result["ratios"].items(): lines.append(f"### {group}") for k, v in vals.items(): pct = f"{v*100:.2f}%" if isinstance(v, float) and -10 < v < 10 else str(v) lines.append(f"- **{k}**: {pct}") lines.append("") if "red_flags" in result: lines.append("## Red Flags"); lines.append("") if not result["red_flags"]: lines.append("_None detected._") for f in result["red_flags"]: lines.append(f"- {f['severity']} **{f['code']}** {f['title']} — {f['evidence']}") return "\n".join(lines) ``` ### Technical Analysis The renderer directly interpolates fields from an input JSON document into Markdown without validating their types or escaping Markdown and raw HTML syntax. Affected fields include the company name, reporting period, executive summary, ratio group and key names, and every red-flag property. Markdown supports structural directives, links, images, and, depending on the downstream renderer, raw HTML. Consequently, an attacker can place Markdown or HTML markup and newline characters in one of these fields to alter ...[truncated 1834 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Define and enforce a strict schema for input documents before rendering: - Require objects and arrays at the expected locations. - Require numeric ratio values. - Require bounded strings for textual fields. - Reject unexpected nested structures and malformed red-flag records. 2. Escape Markdown metacharacters in all data-derived fields, including backslashes, backticks, asterisks, underscores, braces, brackets, parentheses, angle brackets, hash symbols, plus signs, hyphens, periods, exclamation marks, pipes, and newline characters where structural formatting is not intended. 3. Strip or encode raw HTML before generating Markdown. If reports are converted to HTML, configure the Markdown engine to disable raw HTML and sanitize the resulting HTML with an allowlist-based sanitizer. 4. Restrict rendered links and media to approved URL schemes. Disable remote images where possible to prevent tracking requests and unintended data disclosure. 5. Keep trusted formatting templates separate from untrusted report values rather than accepting preformatted Markdown from input data. 6. Add regression tests using fields containing: - Newline-based heading injection - Markdown links and images - Raw HTML tags - `javascript:` and other unsafe URL schemes - Embedded emphasis, lists, and code fences ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared purpose describes a full financial-report analysis skill that can ingest corporate report PDFs, extract and normalize financials, and generate comparative analytics and risk flags. The actual code chunk is a thin orchestration script. Its own docstring and _load_input comments explicitly state that bundled demo mode does not parse PDFs and instead returns a stub for non-JSON inputs. The script primarily routes normalized financial JSON into compute_ratios and detect_red_flags, then formats output. That means part of the declared functionality is supported at a high level (ratio analysis and red-flag detection), but the central ingestion/extraction promise is not implemented here, and comparison features are not present in this chunk. This is a material description-behavior mismatch rather than a minor implementation detail.

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill describes commands that read inputs and write outputs/logs, but it does not declare an explicit tool/permission scope. That creates an authorization ambiguity where a host agent may permit broader file access than users expect, increasing the risk of unintended reads or writes when handling uploaded reports or output paths.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The manifest scopes this skill to extracting and analyzing corporate financial reports, but the README says the bundle may contain unrelated reference tables such as ICD-10, drug aliases, LOINC mappings, and curriculum codes. That indicates a broader multi-domain knowledge design than the skill claims, which is a semantic mismatch in documented behavior/purpose.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
References to ICD-10, drug aliases, LOINC, and curriculum codes imply capability or planned capability in medical and education domains, which is not justified by a skill intended for financial-report extraction and analysis. Even though this is documentation rather than executable logic, it signals context-inappropriate scope for this skill package.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This Python file contains natural-language output strings for red-flag titles entirely in Chinese, which forces a specific language for users of the skill. The file does not offer a language choice or document that the skill is intentionally limited to a Chinese-speaking or region-specific context.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The code accepts non-JSON inputs such as PDFs but does not actually parse them; it silently fabricates a stub record with empty financial statements and then proceeds with ratio/red-flag analysis. In a financial-report analysis skill, this is dangerous because users may trust output that appears to come from a real filing when it is actually derived from placeholder data, leading to misleading investment or risk conclusions.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The JSON includes Chinese-language content and a China-specific ticker/accounting basis ("示例科技", "000001.SZ", "CAS"), which reflects a specific locale without any accompanying justification or indication that the skill offers language/locale choice. Under the stated policy, locale constraints should be documented or user-selectable to avoid forcing a specific language or regional format.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The function accepts both English and Chinese financial field labels such as "营业收入" and "资产总计", which embeds a specific language/locale assumption directly into the skill logic. Because the file does not document this behavior or present it as an explicit locale option, it may violate the policy against forcing a specific language without user opt-in.

Static analysis

No suspicious patterns detected.