Back to skill

Security audit

ArcGIS Pro深度学习训练数据补全

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its ArcGIS data-repair purpose, but it can automatically delete or overwrite files in the chosen dataset folder without confirmation.

Install only if you are comfortable running a local script that modifies the selected training-data folder. Back up the dataset first, check for any existing .emd or .json files you need to keep, and prefer reviewing or patching the cleanup behavior before running it on valuable project directories.

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
main.py:850
Finding

Destructive Deletion of Unrelated JSON and EMD Files

Content
View full analysis

Vulnerability Details

File Location: main.py:850-860
Vulnerability Type: Unrestricted deletion of files based only on extension
Risk Level: High

Complete Code Snippet

python
# 7. 清理旧文件
print("\n[7/8] 清理非标准命名文件...")
removed = []
for f in os.listdir(base):
    fp = os.path.join(base, f)
    if not os.path.isfile(fp):
        continue
    if f.endswith('.emd') and f != 'esri_model_definition.emd':
        os.remove(fp)
        removed.append(f)
    elif f.endswith('.json') and f != 'esri_accumulated_stats.json':
        os.remove(fp)
        removed.append(f)

Technical Analysis

The cleanup logic permanently deletes every top-level .json file except esri_accumulated_stats.json and every top-level .emd file except esri_model_definition.emd. It does not verify that a file was generated by this Skill, belongs to a known obsolete output set, or is safe to remove.

The deletion occurs automatically after output generation, without user confirmation or backup. Extension alone is not a sufficient ownership or safety check. ArcGIS training directories can contain unrelated configuration, annotation, model-definition, or project files using these extensions.

This behavior is disclosed generally in SKILL.md:67, but disclosure does not remove the destructive risk.

Attack Path

  1. A user selects a legitimate ArcGIS training directory containing additional .json or .emd assets.
  2. Alternatively, an attacker supplies a prepared training-data directory containing valuable files with those extensions.
  3. The user runs python main.py <training-directory>.
  4. The script completes metadata generation and enters the cleanup phase.
  5. Every non-allowlisted top-level JSON and EMD file is deleted using os.remove.
  6. Because no backup or recovery mechanism is provided, the affected files may be permanently lost.

Impact Assessment

The script can delete any matching top-level file in the user-selected direc ...[truncated 418 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove the extension-wide cleanup operation.
  • Delete files only from an explicit allowlist of obsolete filenames known to be owned by this tool.
  • Require affirmative user confirmation before deleting any pre-existing file.
  • Move obsolete files to a timestamped backup directory instead of permanently deleting them.
  • Produce a dry-run report listing proposed changes before modifying the directory.
  • Record file ownership through a manifest generated by the Skill and only clean files listed in that manifest.
  • Use case-normalized filename checks if cleanup must support case-insensitive platforms.

T09 · Insecure Skill Coding Practices

Warning
Location
main.py:482
Finding

Output Files Are Silently Truncated and Symbolic Links Are Followed

Content
View full analysis

Vulnerability Details

File Location: main.py:482, with equivalent writes at main.py:538, main.py:634, and main.py:676
Vulnerability Type: Unsafe file replacement and symbolic-link following
Risk Level: Medium

Complete Code Snippet

python
def generate_map_txt(base, img_dir, img_files, label_format, mapping):
    """生成map.txt"""
    map_path = os.path.join(base, "map.txt")

    with open(map_path, 'w', encoding='utf-8') as f:
        if label_format == FORMAT_CYCLEGAN:
            for img_file in img_files:
                stem = os.path.splitext(img_file)[0]
                # CycleGAN: images/A/xxx → images/B/xxx
                target = os.path.join("images", "B", img_file)
                source = os.path.join("images", "A", img_file)
                f.write(f"{source} {target}\n")
        else:
            for img_file in img_files:
                stem = os.path.splitext(img_file)[0]
                if stem in mapping:
                    lbl = mapping[stem]
                    if isinstance(lbl, list):
                        lbl_str = " ".join(lbl)
                    else:
                        lbl_str = lbl
                    f.write(f"images/{img_file} {lbl_str}\n")

    return map_path

The same unsafe write mode is used for all four generated files:

python
with open(map_path, 'w', encoding='utf-8') as f:
with open(emd_path, 'w', encoding='utf-8') as f:
with open(json_path, 'w', encoding='utf-8') as f:
with open(stats_path, 'w', encoding='utf-8') as f:

Technical Analysis

Opening a path with mode 'w' silently truncates an existing file. The implementation does not check whether an output already exists, request confirmation, create a backup, or perform an atomic replacement.

Standard file opening also follows symbolic links. If an attacker can prepare or modify the selected dataset directory, an output such as map.txt can be replaced with a symbolic link to another file. When the Skill r ...[truncated 1429 chars]

Remediation
View remediation

Remediation Suggestions

  • Resolve and validate every output path before writing.
  • Reject an output if os.path.islink(output_path) is true.
  • Verify that the resolved output path remains within the resolved dataset root.
  • Refuse to overwrite existing files unless the user explicitly approves replacement.
  • Back up existing outputs before replacement.
  • Write to a securely created temporary file in the same directory and atomically replace the destination only after successful generation.
  • Use restrictive creation flags such as exclusive creation where replacement is not intended.
  • Recheck the destination immediately before replacement to reduce time-of-check/time-of-use race exposure.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Third-Party Dependencies Are Not Version-Pinned

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-2
Vulnerability Type: Unbounded third-party dependency resolution
Risk Level: Low

Complete Code Snippet

text
numpy
Pillow

Technical Analysis

The dependency declarations do not specify reviewed versions or package hashes. Each installation can therefore resolve to a different release from the configured package index.

This prevents reproducible dependency installation and increases exposure to future compromised releases, unexpected behavior changes, or incompatible versions. The audit found no evidence that numpy or Pillow are currently malicious, misspelled, or retrieved from an unsafe custom source; the issue is the absence of integrity and version controls.

Attack Path

  1. A user or deployment process installs the project dependencies at a later date.
  2. The package resolver selects the newest release allowed by the unbounded requirement.
  3. A selected release is compromised, withdrawn and replaced, or incompatible with the audited implementation.
  4. Package installation or subsequent import executes or loads the newly resolved dependency with the user's privileges.

This path depends on an upstream compromise or unsafe package-index configuration; it is not an active malicious payload in the audited project.

Impact Assessment

A compromised dependency would execute in the Python process with the same privileges as the user running installation or the Skill. Depending on the upstream payload, potential scope could include access to files, environment variables, network resources, and process capabilities available to that account.

Without an upstream compromise, the more likely impact is non-reproducible behavior, compatibility failures, or processing errors.

Remediation
View remediation

Remediation Suggestions

  • Pin dependencies to reviewed versions, for example with exact == constraints.
  • Generate and commit a lock file through a trusted dependency-management workflow.
  • Use hash-verified requirements, such as pip's --require-hashes mode.
  • Regularly review and update pinned versions for published security fixes.
  • Install only from trusted package indexes over authenticated TLS.
  • Scan resolved dependencies for known vulnerabilities in continuous integration.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (11)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The cleanup routine silently removes nonstandard .emd and .json files from the supplied directory without confirmation. Because the target path is fully user-controlled, a mistaken path or a directory containing other project artifacts can lead to irreversible data loss, making this a genuine unsafe destructive action.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill instructs the agent to scan directories, write a Python script, and execute it, but it declares no explicit tool scope or permission boundaries. This creates a capability/authorization mismatch where file read/write behavior is implied without user-visible restriction, increasing the risk of unintended filesystem access or modification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The rule stating that non-standard .emd/.json files are 'automatically cleaned' implies deletion or overwrite of existing files without an explicit warning, backup, or confirmation step. In a data-repair context this is dangerous because users may lose custom metadata, prior experiment artifacts, or unrelated JSON/EMD files in the dataset directory.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code writes multiple files into the user-supplied base directory and later deletes existing .emd and .json files that do not match the expected standard names. Although there are progress print statements, there is no explicit warning before execution in the module docstring or usage text that running the script will modify and remove files in the provided directory.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script deletes any .emd and .json files in the user-supplied target directory that do not match its preferred filenames. That behavior exceeds the stated purpose of 'filling missing files' and can destroy unrelated metadata, model configs, or user-generated JSON content if the operator points it at the wrong folder or a mixed-use dataset directory.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

A natural-language policy issue exists because the skill content forces a specific language without giving the user an opt-in or alternative. The file does not document that the skill is intended only for a Chinese-language audience or environment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module docstring and subsequent CLI messages are written entirely in Chinese, which imposes a specific language on users. There is no indication that the tool is region-specific or that users can opt into another language, so this is a natural-language locale policy concern.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency on numpy is unpinned, so installs may resolve to different versions over time, including versions with known security defects or breaking changes. This creates supply-chain uncertainty and makes the runtime security posture non-reproducible, especially in environments that process external training data.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
numpy
Pillow
# GDAL (osgeo) 是可选依赖,ArcGIS Pro 环境自带
# 如果运行环境没有GDAL,脚本会自动降级使用PIL读取影像

Unverifiable Dependency: numpy has 16 known advisory(ies) (CVE-2014-1859 (Numpy arbitrary file write via symlink attack); CVE-2021-41495 (NumPy NULL Pointer Dereference); CVE-2021-33430 (NumPy Buffer Overflow (Disputed)) +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
82% confidence
Finding

The manifest does not pin numpy, so it is impossible to determine whether the deployed environment will receive a vulnerable or patched version. While the presence of advisories does not prove exploitation here, the lack of version control leaves consumers exposed to potentially affected builds and complicates incident response and auditing.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency on Pillow is unpinned, which means environment setup can pull in an arbitrary latest compatible release rather than a reviewed one. Because Pillow parses image files and this skill handles multiple image formats, version drift increases exposure to image-parsing vulnerabilities and denial-of-service or code-execution flaws in affected releases.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
numpy
Pillow
# GDAL (osgeo) 是可选依赖,ArcGIS Pro 环境自带
# 如果运行环境没有GDAL,脚本会自动降级使用PIL读取影像

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
90% confidence
Finding

Pillow has multiple historical advisories, and because its version is not pinned, the installed package may be a vulnerable build without any visibility from the manifest alone. In this skill's context, Pillow is especially relevant because the tool processes user-supplied image datasets, making parser bugs more reachable than in a non-image-processing package.

Content

No source excerpt is available for this finding.