Back to skill

Security audit

CAD2PDF

Security checks for vulnerabilities and agentic risk

Overview

This CAD-to-PDF skill is mostly purpose-aligned, but it needs review because setup uses root-level unverified dependency installs and DWG conversion may process extra CAD files in the same folder.

Install only in a controlled environment or VM unless you are comfortable with system-wide package changes. Verify the ODA File Converter source and checksum yourself, prefer a virtual environment for Python dependencies, and keep DWG files in a folder without unrelated confidential drawings before converting.

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

Error
Location
SKILL.md:32
Finding

Unpinned and Unverified Third-Party Dependency Installation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 32-45
Vulnerability Type: Supply-chain integrity weakness
Risk Level: High

Vulnerable Code

bash
### Python dependencies
```bash
pip install ezdxf matplotlib --break-system-packages

System dependencies (required only for DWG-to-DXF conversion)

bash
# ODA File Converter
wget "https://www.opendesign.com/guestfiles/get?filename=ODAFileConverter_QT6_lnxX64_8.3dll_27.1.deb" -O /tmp/ODAFileConverter.deb
sudo dpkg -i /tmp/ODAFileConverter.deb
sudo apt-get install -y libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xkb1

Technical Analysis

The documented installation procedure installs Python packages without pinned versions or cryptographic hashes. It also downloads a Debian package from a mutable remote URL and installs it with root privileges without checking an expected checksum or package signature.

HTTPS protects the download in transit under normal conditions, but it does not establish that the downloaded artifact is the exact version audited by this project. The artifact could change if the vendor updates the URL, the vendor infrastructure or account is compromised, or the download endpoint is otherwise manipulated.

The --break-system-packages option also bypasses protections intended to prevent pip from modifying an externally managed Python environment. This increases the possibility of dependency conflicts and system-wide package contamination.

Attack Path

  1. An attacker compromises a dependency distribution channel, package release account, vendor download endpoint, or upstream package.
  2. A user follows the installation instructions.
  3. pip resolves an unpinned package version, or wget retrieves a modified Debian artifact from the mutable URL.
  4. Package installation executes package build or installation logic.
  5. In the Debian package case, `sudo dpkg ...[truncated 951 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin exact Python dependency versions in a requirements or lock file.
  2. Record and enforce package hashes, for example with pip install --require-hashes -r requirements.txt.
  3. Install Python packages in a dedicated virtual environment rather than using --break-system-packages.
  4. Pin the exact ODA File Converter release and publish its expected SHA-256 checksum.
  5. Verify the downloaded artifact before invoking sudo dpkg -i; abort installation if verification fails.
  6. Prefer a vendor-provided repository with signed package metadata when available.
  7. Consider downloading and verifying packages without elevated privileges, using privilege elevation only for the final verified installation step.
  8. Document the trusted source, expected version, checksum, and update-review process.

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
cad2pdf.sh:75
Finding

DWG Conversion Unnecessarily Processes the Entire Input Directory

Content
View full analysis

Vulnerability Details

File Location: cad2pdf.sh, lines 75-84
Vulnerability Type: Excessive local file access and failure to minimize processing scope
Risk Level: Medium

Vulnerable Code

bash
if [[ "$ext" == "dwg" ]]; then
    info "DWG file, converting to DXF first..."
    command -v ODAFileConverter &>/dev/null || { error "ODA File Converter is missing"; exit 1; }

    export QT_QPA_PLATFORM=offscreen
    export QT_QPA_PLATFORM_PLUGIN_PATH=/usr/bin/ODAFileConverter_27.1.0.0/plugins

    local tmpdir=$(mktemp -d)
    ODAFileConverter "$(dirname "$input")" "$tmpdir" ACAD2018 DXF 0 0 2>/dev/null

    local dxf_file="$tmpdir/$(basename "${input%.*}").dxf"

Technical Analysis

The command-line interface accepts one DWG input file, but the wrapper passes the parent directory of that file to ODAFileConverter. ODA File Converter uses directory-oriented input and output parameters, so the converter may enumerate and process other supported drawing files located beside the requested input.

This behavior violates least-privilege and data-minimization principles. The conversion only requires access to one selected drawing, but the external process is given a directory potentially containing unrelated or confidential files.

Shell command injection was not identified in this code: the input directory and output directory are quoted. The weakness concerns the scope of file enumeration and processing rather than shell interpretation.

Attack Path

  1. A user requests conversion of one DWG file stored in a directory containing other drawings.
  2. The wrapper derives the directory using dirname.
  3. The entire directory is supplied as the input location to ODAFileConverter.
  4. The converter enumerates and may read or convert other supported files in that directory.
  5. Converted copies of those unrelated drawings are written into the temporary output directory.
  6. Those files remain av ...[truncated 1057 chars]
Remediation
View remediation

Remediation Suggestions

  1. Create a private staging input directory with mktemp -d.
  2. Copy only the explicitly selected DWG file into that staging directory.
  3. Create a separate private output directory and pass the two staging directories to ODA File Converter.
  4. Retrieve only the DXF corresponding to the staged input file.
  5. Register an EXIT trap immediately after creating temporary directories so cleanup occurs on success, failure, interruption, or an external converter error.
  6. Preserve restrictive temporary-directory permissions and avoid making generated files readable by other users.
  7. Validate that the expected output is a regular file before passing it to the Python renderer.
  8. Document that only the requested file is processed and add a regression test using a directory containing multiple DWG files.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • 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 (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

整体上,这段代码的主要目的与描述高度相关,确实是在做CAD图纸转矢量PDF,并包含拆页、中文文字处理、标注修复和填充显示等支持逻辑。但存在几项重要不一致:第一,描述宣称支持DWG/DXF,而代码入口和解析仅针对.dxf文件,使用ezdxf.readfile读取,未见任何DWG读取或外部转换流程;第二,描述中的“完整渲染”较泛化,而代码明确采用黑白输出(ColorPolicy.BLACK)、填充为近似模式(HatchPolicy.SHOW_APPROXIMATE_PATTERN),并通过字体替换到Noto Sans CJK作为兼容性补救,不能等同于普适、完整保真渲染;第三,所谓“自动按图框拆页”并非通用图框检测,而是基于颜色6(粉紫色)闭合LWPOLYLINE和尺寸阈值的特定启发式,若图框不符合该规则则无法工作。基于这些差异,尤其是DWG支持缺失,判断为描述与实际行为存在实质性不匹配。

Content

No source excerpt is available for this finding.

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · cad2pdf.sh (reported line 83)May include surrounding context.

sh
ODAFileConverter "$(dirname "$input")" "$tmpdir" ACAD2018 DXF 0 0 2>/dev/null

        local dxf_file="$tmpdir/$(basename "${input%.*}").dxf"
        [[ ! -f "$dxf_file" ]] && { error "DWG转DXF失败"; rm -rf "$tmpdir"; exit 1; }

        python3 "$PYTHON_SCRIPT" "$dxf_file" "$output" --paper "$paper" --dpi "$dpi"
        rm -rf "$tmpdir"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
94% confidence
Finding

The skill instructs users to download and install a third-party .deb from the internet and execute it with sudo. In a skill context, this is dangerous because it normalizes privileged installation of unpinned external software, which can lead to full system compromise if the package is malicious, tampered with, or later replaced upstream.

Content

Scanner excerpt · SKILL.md (reported line 41)May include surrounding context.

bash
# ODA File Converter
wget "https://www.opendesign.com/guestfiles/get?filename=ODAFileConverter_QT6_lnxX64_8.3dll_27.1.deb" -O /tmp/ODAFileConverter.deb
sudo dpkg -i /tmp/ODAFileConverter.deb
sudo apt-get install -y libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xkb1

# 中文字体

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
92% confidence
Finding

Running apt-get install with sudo grants root-level changes to the host system. While common for dependency setup, embedding such commands in a skill increases risk because users may execute them without review, expanding the attack surface and enabling unintended or hostile system modification if package sources are compromised.

Content

Scanner excerpt · SKILL.md (reported line 42)May include surrounding context.

md
# ODA File Converter
wget "https://www.opendesign.com/guestfiles/get?filename=ODAFileConverter_QT6_lnxX64_8.3dll_27.1.deb" -O /tmp/ODAFileConverter.deb
sudo dpkg -i /tmp/ODAFileConverter.deb
sudo apt-get install -y libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xkb1

# 中文字体
sudo apt-get install -y fonts-noto-cjk

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
88% confidence
Finding

This command installs fonts with sudo, which is less inherently risky than installing arbitrary third-party binaries but still performs privileged system modification. In the context of an agent skill, encouraging root execution for setup is a security concern because it trains users to run commands with elevated privileges unnecessarily.

Content

Scanner excerpt · SKILL.md (reported line 45)May include surrounding context.

sudo apt-get install -y libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xkb1

中文字体

sudo apt-get install -y fonts-noto-cjk

text

## 使用方法

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The user-facing title and usage text are written entirely in Chinese, and the rest of the help/output strings follow the same pattern. For a general-purpose conversion script, this effectively imposes a specific language/locale without opt-in or a documented region-specific justification, which matches the language-policy concern in SQP-3.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.