Back to skill

Security audit

statdata-transfer

Security checks for vulnerabilities and agentic risk

Overview

This is a legitimate local statistical data converter, but it needs Review because some file discovery and optional execution/install paths are broader than users may expect.

Install only if you are comfortable with a local converter that reads and writes statistical data files. Use explicit input and output paths, avoid running it in directories containing unrelated sensitive CSVs, do not enable allow_r_exec for untrusted R/Minitab/EpiData files, and prefer installing dependencies in an isolated environment with reviewed versions.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T08 · Insecure Dependencies

Warning
Location
scripts/check_env.py:59
Finding

Optional Dependency Installer Ignores Declared Version Constraints

Content
View full analysis

Vulnerability Details

File Location: scripts/check_env.py:59-68
Vulnerability Type: Unconstrained third-party package installation
Risk Level: Medium

Vulnerable Code

python
# 先尝试 conda(更快,二进制包)
result = subprocess.run(
    ["conda", "install", "-y", pkg, "-c", "conda-forge"],
    capture_output=True, text=True, timeout=300
)
if result.returncode != 0:
    # 降级到 pip
    result = subprocess.run(
        [sys.executable, "-m", "pip", "install", pkg],
        capture_output=True, text=True, timeout=300
    )

Technical Analysis

The optional installer passes bare package names from REQUIRED_PACKAGES to Conda or pip. It does not apply the version constraints declared in requirements.txt, and it does not use a lock file or package hashes.

Consequently, the artifacts installed by python scripts/check_env.py --install are selected dynamically from Conda Forge or the configured Python package index. Some dependencies include native binary components. Although installation requires the explicit --install option and no shell command injection is present, installation scripts and subsequently imported package code execute with the privileges of the Python environment owner.

The fallback also changes package sources automatically: a failed Conda installation causes an installation attempt from pip. This makes the resulting dependency set less predictable and undermines the security benefit claimed by the version constraints in requirements.txt.

Attack Path

  1. A user explicitly runs python scripts/check_env.py --install, as documented by the Skill.
  2. The script identifies a missing dependency.
  3. The dependency is requested from Conda Forge using only its package name and no fixed version or integrity hash.
  4. If the Conda operation fails, the script requests the package from the configured pip index, again without a fixed version or hash.
  5. A compromised repository a ...[truncated 797 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace bare package installation with a reviewed lock file containing exact versions and cryptographic hashes.
  2. For pip, use a command such as pip install --require-hashes -r requirements.lock.
  3. For Conda, use an explicit environment lock generated for each supported platform.
  4. Do not silently switch package repositories. Require the user to choose Conda or pip explicitly.
  5. Ensure the installer applies the same constraints as requirements.txt if a fully locked installation is not feasible.
  6. Separate core and optional dependencies so that only packages required for the requested format are installed.
  7. Display the exact repository, package version, and planned changes before requesting final installation confirmation.
  8. Prefer installation into an isolated virtual environment rather than modifying a shared or system Python environment.

T05 · Unauthorized Access and Privilege Escalation

Note
Location
scripts/reader_epinfo.py:58
Finding

EpiInfo Companion Discovery Reads Unspecified Neighboring CSV Files

Content
View full analysis

Vulnerability Details

File Location: scripts/reader_epinfo.py:58-76
Vulnerability Type: Excessive filesystem access during automatic companion-file discovery
Risk Level: Low

Vulnerable Code

python
# Priority 1: Look for CSV with same name as project
base_name = os.path.splitext(os.path.basename(prj_path))[0]
for ext in [".csv", ".txt", ".tsv"]:
    candidate = os.path.join(base_dir, base_name + ext)
    if os.path.exists(candidate):
        return candidate, "csv"

# Priority 2: Look for any CSV in the same directory
for f in os.listdir(base_dir):
    if f.endswith(".csv") and f != os.path.basename(prj_path):
        candidate = os.path.join(base_dir, f)
        # Check if it has matching headers
        try:
            with open(candidate, 'r', encoding='utf-8', errors='replace') as csvfile:
                reader = csv.reader(csvfile)
                header = next(reader, [])
                if header and any(fn in header for fn in field_names if fn):
                    return candidate, "csv"
        except Exception:
            pass

The selected file is later loaded at scripts/reader_epinfo.py:233-251:

python
actual_data_file = data_file
data_file_type = "csv"
if actual_data_file is None:
    actual_data_file, data_file_type = _find_data_file(prj_path, field_names)

# Read data
df = pd.DataFrame()
if actual_data_file:
    try:
        if data_file_type == "csv":
            read_kwargs = {"encoding": encoding} if encoding else {}
            df = pd.read_csv(actual_data_file, **read_kwargs)

Technical Analysis

If the caller does not supply data_file and no exact same-basename companion is found, _find_data_file enumerates the entire directory containing the selected EpiInfo project. It opens every lowercase .csv file in that directory until it finds one containing at least one project field name.

This behavior goes beyon ...[truncated 1925 chars]

Remediation
View remediation

Remediation Suggestions

  1. Require callers to provide data_file whenever an exact same-basename companion does not exist.
  2. Remove the fallback that scans arbitrary sibling CSV files.
  3. If discovery must remain available, return a list of candidate filenames without opening them and require explicit user selection.
  4. Require stronger matching than one shared column name, such as an exact or high-confidence schema match.
  5. Clearly disclose every additional file before it is opened and obtain user confirmation.
  6. Record the selected companion path in warnings or audit output before loading its contents.
  7. Resolve and validate an explicitly supplied companion path according to the host application's permitted filesystem scope.
  8. Add tests demonstrating that unrelated sibling files are never opened without explicit authorization.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (43)

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README asserts that opt-in R execution is 'sandboxed by default,' but the surrounding text only describes gating on allow_r_exec=True, static templates, and CLI argument passing. Those controls reduce accidental execution paths, but they are not a sandbox and do not constrain what the R interpreter or invoked packages can do on the local system once launched. This can mislead users into trusting risky file conversions or enabling R execution under a false sense of isolation.

Content

No source excerpt is available for this finding.

Ae2

Medium
Category
analysis-evasion
Confidence
90% confidence
Finding

Artifact content does not match its filename extension

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This JSON contains multiple natural-language values in Chinese, such as status, dependency, architecture, and remaining-work descriptions. Because the file does not indicate that Chinese is optional or justified by a region-specific constraint, it appears to impose a specific language without user opt-in, matching the language/locale policy category.

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/check_env.py (reported line 59)May include surrounding context.

python
print(f"\n{_bilingual(f'Installing {pkg}...', f'正在安装 {pkg}...')}")
                try:
                    # 先尝试 conda(更快,二进制包)
                    result = subprocess.run(
                        ["conda", "install", "-y", pkg, "-c", "conda-forge"],
                        capture_output=True, text=True, timeout=300
                    )

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/check_env.py (reported line 65)May include surrounding context.

python
)
                    if result.returncode != 0:
                        # 降级到 pip
                        result = subprocess.run(
                            [sys.executable, "-m", "pip", "install", pkg],
                            capture_output=True, text=True, timeout=300
                        )

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module docstring and later generated labels/notes are written in Chinese, indicating the skill presents its descriptions and metadata in a fixed locale. The policy requires avoiding forced language or locale constraints unless the user is given a choice or the restriction is clearly documented as justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code constructs values such as "名义变量", "关系名", and "实例数" for metadata that downstream users will see. This is a natural-language locale restriction embedded in code without any visible opt-in or documented regional justification.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The top-level docstring says the file contains core data structures, utility functions, and the read_stat_file entrypoint, which frames the module as read-oriented infrastructure. Later, the module defines and exports write_stat_file and convert_stat_file, adding write/transform capabilities not reflected in that documentation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

This code exposes a write_stat_file interface that writes DataFrames to output files, which is a safety-relevant file modification operation. The function docstring describes supported formats but does not warn about overwriting or creating files, and there is no confirmation prompt or user-facing disclosure in this file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring is written entirely in Chinese, and later user-facing notes and warnings are also emitted in Chinese-first bilingual form. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is clearly documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring and later user-facing strings are written in Chinese only, indicating the skill is designed to communicate in a fixed language. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The RuntimeError message shown to users during parse failure is Chinese-only and does not provide an alternative language or any opt-in mechanism. This creates a locale-policy issue because the skill imposes one language on all users without documenting that the tool is region- or language-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code file contains extensive natural-language documentation entirely in Chinese, including the module heading and operational descriptions, without indicating that language selection is configurable or limited to a justified region-specific context. The policy requires avoiding forced language/locale behavior unless the user is given a choice or the constraint is clearly documented and justified.

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 header describes the skill entirely in Chinese, indicating a fixed language/locale expectation in the skill’s natural-language surface. Under the policy, forcing a specific language without user opt-in is a locale-policy concern unless the constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

This subprocess call itself is not shell-injection prone because it passes an argument list to subprocess.run rather than invoking a shell, and the R script body is static. However, in this skill's context it launches Rscript to process attacker-controlled .rda/.rds content, and the code correctly notes that R's readRDS()/load() deserialization may execute embedded code from untrusted files. If a caller enables allow_r_exec=True on untrusted input, this becomes an explicit local code-execution path.

Content

Scanner excerpt · scripts/reader_r.py (reported line 37)May include surrounding context.

python
with open(script_path, "w", encoding="utf-8") as f:
            f.write(script_body)
        cmd = [rscript_path, script_path] + [str(a) for a in args]
        result = subprocess.run(
            cmd, capture_output=True, text=True, timeout=timeout,
            encoding="utf-8", errors="replace",
        )

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code contains user-facing natural-language text and warnings predominantly in Chinese, such as the module description and several runtime messages. Under the language/locale policy, forcing a specific language without user opt-in or documented regional justification is a policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code includes natural-language strings that are primarily Chinese and bilingual, but there is no indication that language selection is user-configurable or that the skill is intentionally limited to a Chinese-speaking context. Under the policy, forcing a specific language or locale without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
79% confidence
Finding

The function is documented as an unsupported-reader path that should only report inability to parse FST files, but its raised error message goes further by prescribing execution of an external R command using the caller-supplied filepath. That creates an intent mismatch between 'not supported' and code/documentation that actively steers consumers toward out-of-band command execution on the input path.

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/reader_v14.py (reported line 295)May include surrounding context.

python
with open(script_path, "w", encoding="utf-8") as f:
            f.write(script_body)
        cmd = [rscript_path, script_path] + [str(a) for a in args]
        result = subprocess.run(
            cmd, capture_output=True, text=True, timeout=timeout,
            encoding="utf-8", errors="replace",
        )

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/writer.py (reported line 356)May include surrounding context.

python
with open(script_path, "w", encoding="utf-8") as f:
            f.write(script_body)
        cmd = [rscript_path, script_path] + [str(a) for a in args]
        result = subprocess.run(
            cmd, capture_output=True, text=True, timeout=timeout,
            encoding="utf-8", errors="replace",
        )

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This code invokes a local R interpreter on the provided file and then reads the generated CSV, which is a safety-relevant subprocess operation on potentially untrusted input. Although some error paths mention the risk, there is no visible confirmation prompt, print/log statement, or inline user-facing disclosure at the actual execution site to warn that external code/tooling is being run.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code claims jamovi embedded analysis content is not read or propagated for privacy reasons, but it still exposes the full ZIP member list via csv_files and analysis_files metadata. Even without parsing JSON, leaking embedded file names can disclose sensitive project structure, note presence, or analysis artifact names from untrusted uploads, contradicting the stated security posture.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code writes the requested CSV/TSV file and, when metadata is present, silently creates a second file named *_metadata.json containing embedded metadata. Although the docstrings mention this behavior, there is no confirmation prompt or user-facing disclosure when the extra file is created, which can surprise users and expose metadata they did not expect to be written separately.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

SQP-3 applies to all file types and covers natural-language policy violations such as forcing a specific language without user opt-in. This markdown report presents all user-facing content in Chinese and does not indicate that users may choose another language or that the skill is intentionally region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

This Python file includes direct conversion and write examples that create output files via convert_stat_file and write_stat_file. Although these writes are central to the example's purpose, the snippet provides no user-facing warning, comment, or note about local file modification or possible overwrite behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.