Back to skill

Security audit

smart-report

Security checks for vulnerabilities and agentic risk

Overview

This data-reporting skill is coherent, but it can run generated Python and evaluate chart JavaScript in ways that may execute unsafe code if inputs are hostile.

Review before installing. Use this skill only with trusted datasets, chart specs, and generated chart HTML; avoid letting untrusted prompts or files supply transform_code or report_spec chart paths. Prefer running it in a constrained environment with limited filesystem and network access, and consider lockfile/hash controls for dependencies.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/data_transformer.py:327
Finding

Transform Sandbox Escape Through Exposed NumPy Native-Library Interfaces

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/report_assembler.py:118
Finding

Untrusted Chart JavaScript Is Evaluated by Node.js and Embedded into Generated Reports

Content
View full analysis
Path: candidates = [ Path(chart_path), charts_dir / chart_path, spec_dir / chart_path, ] for cand in candidates: if cand.is_file(): return cand return None ``` The extracted value is embedded directly in the generated report: ```python opt_lines = [f' {json.dumps(s_id)}: {payloads[s_id]["option_js"]}' for s_id, pl in payloads.items() if pl['kind'] == 'echarts'] init_js = ( 'var __SR_OPTIONS = {\n' + ',\n'.join(opt_lines) + '\n};\n' + _build_init_js() ) ``` For static export, the same value is evaluated by Node.js: ```javascript const sandbox = {}; vm.createContext(sandbox); let option; try { vm.runInContext(`var __opt = ( ${item.option_js} );`, sandbox); option = sandbox.__opt; ...[truncated 3244 chars]
Remediation
View remediation
`, `&`, U+2028, and U+2029, or place JSON in a non-executable `application/json` element. 8. Run static export in a restricted subprocess with no network access, minimal filesystem access, resource limits, and an unprivileged account. 9. Add negative tests using object literals containing immediate expressions, getters, constructor chains, oversized data structures, and path-traversal references. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:15
Finding

Mutable Dependency Ranges Permit Unreviewed Supply-Chain Changes

Content
View full analysis
=3.0.1,<4.0.0 numpy>=2.4.3,<3.0.0 openpyxl>=3.1.5,<4.0.0 xlrd>=2.0.1,<3.0.0 ``` ```text python-docx==1.2.0 python-pptx==1.0.2 resvg-py>=0.4,<0.6 ``` The documented installation command is: ```text pip install -r requirements.txt ``` ### Technical Analysis Several dependencies use broad version ranges, and neither dependency manifest provides package hashes. Consequently, two installations performed at different times can select different artifacts even when the audited project files are unchanged. Installation trusts the package index configured for pip at execution time. If an allowed future release is compromised, unexpectedly incompatible, or substituted through a malicious package index, it can enter the environment without review of this repository. Exact versions alone do not fully solve this problem because an index-side artifact can still differ. Cryptographic hashes are required to bind installation to reviewed distributions. This finding does not establish that any currently named package is malicious. It identifies a supply-chain control weakness that permits unreviewed code changes during installation. ### Attack Path 1. A user follows the documented `pip install -r requirements.txt` workflow. 2. Pip queries the currently configured package index. 3. The resolver selects any package version satisfying the declared ranges. 4. A newly released, compromised, or substituted artifact satisfies those constraints. 5. Pip downloads and installs the artifact without checking it against repository-maintained hashes. 6. Package installation or later import executes code that was not included in the audited project snapshot. ### Impact Assessment A compromised dependency executes ...[truncated 463 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (48)

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% 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/REFERENCE.md (reported line 69)May include surrounding context.

md
**Numeric coercion is observable:** string columns are cleaned (currency symbols → thousands separators → `%` → Chinese magnitude suffixes `亿`/`万`/`千`, so `8.5万` → `85000`) and then coerced. If only *some* cells fail to parse but ≥50% succeed, the column still becomes numeric with the failures set to missing, and an advisory is emitted naming the column and the number of discarded cells. Below 50% the column is left as text. Previously a single stray `-` silently degraded a whole column to string with no warning.

exec() call detected

High
Category
Dangerous Code Execution
Confidence
94% confidence
Finding

This code executes LLM-generated Python via exec(), which is inherently dangerous because the surrounding blacklist/AST checks are incomplete as a sandbox boundary. The execution context exposes powerful live objects such as pandas, numpy, and a builtins mapping; attackers can often reach dangerous functionality through object graph traversal, denial-of-service primitives, or overlooked library methods despite superficial filtering.

Content

Scanner excerpt · scripts/data_transformer.py (reported line 368)May include surrounding context.

python
# P2-print 修复:把 transform 代码里的 print 重定向到 stderr,
            # 避免污染 cli.py 末尾输出到 stdout 的 JSON 契约。
            with contextlib.redirect_stdout(sys.stderr):
                exec(code, ns)
        except TimeoutError:
            raise TransformError(
                f"转换代码执行超时(超过 {self.timeout} 秒),可能存在无限循环",

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/report_assembler.py (reported line 338)May include surrounding context.

python
manifest_path = out_dir / '_manifest.json'
    manifest_path.parent.mkdir(parents=True, exist_ok=True)
    manifest_path.write_text(json.dumps(manifest, ensure_ascii=False), encoding='utf-8')
    env = os.environ.copy()
    env['NODE_PATH'] = str(skill_root / 'scripts')
    try:
        proc = subprocess.run(

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill clearly instructs the agent to read local files, write outputs, inspect environment/runtime paths, invoke shell commands, and potentially use optional export dependencies, yet it declares no explicit tool scope or permission boundaries. That creates a real least-privilege gap: an agent may execute broad file and shell operations under this skill without user-visible guardrails, increasing the blast radius if the skill is misused or if downstream prompts become adversarial.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The activation triggers include broad phrases like '写报告', '分析报告', '汇报材料', and 'report', which are common in normal conversation and not tightly bounded to the specific data-to-report workflow. Over-broad activation can cause the skill to engage in unintended contexts, leading the agent to read files, generate artifacts, or run shell-based pipelines when the user did not clearly request this high-capability behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The docstring states that lang is forced to 'zh' or 'en', and the validation later rejects any other locale. This is a language/locale policy constraint that does not offer broader user choice or document a justified region-specific limitation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The validation explicitly rejects any lang value except 'zh' and 'en'. That hard-coded restriction forces a limited language policy without offering user opt-in to other locales or documenting a justified compliance reason.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The module docstring and many user-facing strings in this CLI are written only in Chinese, which imposes a specific language on users. Under the stated policy, forcing a language without offering a user choice or documenting a justified locale restriction is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
75% confidence
Finding

Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Content

Scanner excerpt · scripts/cli.py (reported line 33)May include surrounding context.

python
ok_all = True
    for name, min_ver in REQUIREMENTS:
        try:
            mod = __import__(name)
            ver = getattr(mod, '__version__', 'unknown')
            ok = _version_ok(ver, min_ver)
        except ImportError as e:

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The parser help text, option descriptions, and validation errors are consistently Chinese-only, so users are required to interact in that locale. Although a --lang flag exists, it controls chart text rather than CLI interface language, so it does not mitigate the policy issue for command help and errors.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code file contains natural-language strings entirely in Chinese, including the top-level docstring and later CLI/help text, with no indication that users may choose another language. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless clearly justified as region-specific, which is not documented here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The file raises exceptions, prints summaries, and emits advisories/warnings using Chinese-language strings throughout the implementation. Because these are direct user-visible outputs and no locale negotiation or configuration exists, the skill effectively mandates one language for all users.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The top-level docstring states that the sandboxed builtins prohibit access to open/exec/eval/import and presents this as a safety property. However, the executor later assigns ns['builtins'] = safe_builtins, meaning builtins is in fact exposed to executed code, albeit in a restricted form. This is an active contradiction between the stated sandbox model and the implemented 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 file performs a safety-critical operation by executing user/LLM-supplied code via a sandbox, and the surrounding documentation explicitly says execution proceeds without user confirmation. While the file documents the sandboxing, it lacks a user-facing confirmation or disclosure at the execution point for this risky operation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script executes manifest-provided JavaScript via vm.runInContext, while the comment explicitly downplays the risk. Even in a VM context, untrusted JavaScript can still trigger denial of service, unsafe code paths in loaded libraries, and in some Node.js configurations may enable sandbox escape or access to powerful globals; treating a locally generated manifest as inherently trusted is a fragile trust assumption. In this skill context, the danger is increased because the file is an automation/export utility likely to process generated data without human review, making supply-chain or upstream data tampering more plausible.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module docstring and all user/developer-facing explanatory text in this file are written exclusively in Chinese, with no indication that another language is supported or that the user can choose a locale. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This Python file contains natural-language instructions and slide text entirely in Chinese, including the module description and generated presentation labels. Under the policy rule, forcing a specific language without user opt-in is a locale/language policy violation, and there is no indication in this file that users can choose another language or that the constraint is justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This Python script's user-facing natural language is entirely in Chinese, including the module docstring, usage text, test names, and printed status messages, and there is no indication that the user can select another language for the script's own interface. Under the policy rule for language/locale constraints, forcing a specific language without opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/regression_check.py (reported line 51)May include surrounding context.

python
def run_cli(args, timeout=90):
    t0 = time.time()
    proc = subprocess.run([sys.executable, str(CLI)] + [str(a) for a in args],
                          capture_output=True, text=True, timeout=timeout)
    dt = time.time() - t0
    out = None

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/regression_check.py (reported line 63)May include surrounding context.

python
return proc.returncode, out, proc.stderr, dt

def run_dp(args, timeout=60):
    proc = subprocess.run([sys.executable, str(DP)] + [str(a) for a in args],
                          capture_output=True, text=True, timeout=timeout)
    return proc.returncode, proc.stdout, proc.stderr

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/regression_check.py (reported line 752)May include surrounding context.

python
rec("P1-8-requirements改用兼容区间",
    'pandas>=' in _req and 'pandas==' not in _req and 'numpy>=' in _req,
    f"{_req[:80]}")
_proc = subprocess.run([sys.executable, str(CLI), '--doctor'], capture_output=True, text=True, timeout=60)
try:
    _doc = json.loads(_proc.stdout)
    rec("P1-8---doctor输出版本矩阵",

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/regression_check.py (reported line 954)May include surrounding context.

python
(ROOT / 'report_spec.json').write_text(json.dumps(_spec, ensure_ascii=False), encoding='utf-8')
    # 组装(scan 模式 + 仅 html)
    _out_html = ROOT / 'report.html'
    _proc = subprocess.run([sys.executable, str(_RA), '--spec', str(ROOT / 'report_spec.json'),
                            '--charts-dir', str(_rchart_dir), '--output', str(_out_html),
                            '--ledger', str(ROOT / 'ledger.json')],
                           capture_output=True, text=True, timeout=120)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/regression_check.py (reported line 982)May include surrounding context.

python
# ── R4~R10:论点台账(claims.json)形式校验 ──
    def run_ra(extra_args, out_name='report_claims.html', timeout=120):
        _proc = subprocess.run([sys.executable, str(_RA),
                                '--spec', str(ROOT / 'report_spec.json'),
                                '--charts-dir', str(_rchart_dir),
                                '--output', str(ROOT / out_name)] + [str(a) for a in extra_args],

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/regression_check.py (reported line 1092)May include surrounding context.

python
"annotation": "本图并列展示两条系列。"},
    ]
    (ROOT / 'report_spec_ph.json').write_text(json.dumps(_spec_ph, ensure_ascii=False), encoding='utf-8')
    _proc10 = subprocess.run([sys.executable, str(_RA),
                              '--spec', str(ROOT / 'report_spec_ph.json'),
                              '--charts-dir', str(_rchart_dir),
                              '--output', str(ROOT / 'report_ph.html'),

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/regression_check.py (reported line 1134)May include surrounding context.

python
(ROOT / 'report_spec_narr.json').write_text(json.dumps(_spec_narr, ensure_ascii=False), encoding='utf-8')
    _claims_narr = [{"id": "c1", "claim": "有图章节的主张", "evidence": ["s1"], "section": "s1"}]
    (ROOT / 'claims_narr.json').write_text(json.dumps(_claims_narr, ensure_ascii=False), encoding='utf-8')
    _proc11 = subprocess.run([sys.executable, str(_RA),
                              '--spec', str(ROOT / 'report_spec_narr.json'),
                              '--charts-dir', str(_rchart_dir),
                              '--output', str(ROOT / 'report_narr.html'),

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
assets/echarts.min.js:45

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/data_transformer.py:25

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/regression_check.py:149