T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/fill_pdf_form_with_annotations.py:13- Finding
Untrusted Fonts Are Persistently Installed into User or System Font Directories
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is mostly a PDF helper, but one form-filling path can silently make persistent host font/configuration changes from workspace-adjacent files.
Review carefully before installing. Use this only in an isolated workspace or container, avoid running annotation-based form filling on untrusted PDFs or directories, inspect any nearby assets/fonts folder first, and work on copies of sensitive PDFs. Do not let the skill silently change font directories, renderer policy, ownership, or caches; require explicit approval for any persistent environment change.
scripts/fill_pdf_form_with_annotations.py:13Untrusted Fonts Are Persistently Installed into User or System Font Directories
forms.md:302Skill Instructions Encourage Silent Modification of Shared Runtime and Security State
SKILL.md:235OCR Setup Recommends Unpinned Package Installation
This is a clear mismatch. The declared description says the skill should be used for essentially any PDF-related task. However, the supplied code only loads a JSON structure with form_fields, inspects label_bounding_box and entry_bounding_box coordinates, checks rectangle intersections on the same page, validates entry box height against font size, and emits success/failure messages. There is no PDF parsing, rendering, text extraction, table extraction, merging, splitting, form filling into PDFs, OCR, encryption, or any other direct PDF operation. The actual code’s purpose is specialized QA/validation for form field layout metadata, not a general PDF utility.
The declared description presents this skill as a general-purpose PDF toolkit covering numerous operations such as text extraction, merging, splitting, OCR, form filling, and encryption. The supplied code, however, only renders PDF pages to PNG images and saves them. While this is PDF-related, it is not explicitly one of the described capabilities except loosely adjacent to 'extracting images,' which usually means pulling embedded images from a PDF rather than rasterizing pages. The primary purpose of the code is materially narrower and different from the declared broad functionality, so this is a description-behavior mismatch.
The declared description presents a broad PDF-processing skill, but the actual code chunk performs a narrow image-annotation task: it reads field metadata from JSON and overlays bounding boxes onto an image for validation. It does not read, modify, generate, merge, split, OCR, encrypt, or otherwise process PDF files in this chunk. Its primary purpose is materially different from the declared PDF utility description, so this is a clear mismatch.
The declared description presents this as an all-purpose PDF skill, triggered whenever the user wants to do anything with PDFs. The supplied code chunk has a much narrower purpose: it inspects PDF form annotations using pypdf and exports form field metadata to JSON. It does not implement the broad set of PDF operations claimed in the description. While the code does operate on PDFs, its actual behavior is materially narrower and specifically focused on form-field introspection, which is not clearly represented in the description. Therefore the description does not accurately represent what this code chunk actually does.
The declared description promises a broad PDF toolkit usable for essentially anything involving PDFs. The supplied code, however, has a much narrower and materially different purpose: it inspects a non-fillable PDF using pdfplumber to identify text labels and geometric elements relevant to reconstructing form fields, then saves those coordinates as JSON. While this loosely falls under PDF text extraction/analysis, it does not implement most of the declared capabilities and its primary purpose is specialized form-structure extraction rather than general PDF handling. This is a description/behavior mismatch due to the materially narrower actual behavior.
The activation rule says to use this skill whenever the user wants to do anything with PDFs or even merely mentions a .pdf file, which is excessively broad. In an agent system, that can cause the skill to be selected in irrelevant or sensitive contexts, increasing the chance of unintended file access, shell execution, or incorrect handling of protected documents.
The skill provides Python and shell examples that imply file read/write and shell execution capability, but it does not declare any explicit tool scope such as permissions or allowed-tools. In an agent environment, that ambiguity can lead to over-privileged invocation or unsafe assumptions about what the skill is authorized to do.
The guide includes a qpdf example for removing a password and decrypting a PDF but provides no warning about authorization, ownership, or protected-document handling. In a skill meant for agent use, this can normalize bypass-style workflows and encourage processing of encrypted documents without verifying the user is permitted to do so.
This section broadens the skill from PDF form filling into runtime remediation and system configuration, including machine-visible font registration, cache/index refresh, ownership normalization, and renderer configuration changes. In an agent setting, such instructions can induce privileged or persistent environmental modifications that exceed the user's task and create opportunities for unintended system impact.
The recovery guidance expands a PDF-processing skill into host-level environment maintenance by suggesting actions like rebuilding font state, reconciling shared font indexes, adjusting cache ownership, and registering fonts in machine-visible locations. These are system configuration changes unrelated to ordinary document handling and could modify shared runtime state, weaken isolation boundaries, or create persistence on the host if followed by an agent.
The instruction to keep recovery actions silent unless a retry fails suppresses user visibility into environment-changing behavior. Concealing retries that may rebuild caches, modify font state, or alter machine-visible configuration undermines informed consent and makes unauthorized system changes harder to detect or audit.
This markdown reference includes many examples that save new files, extract text/images from PDFs, decrypt documents, and even replace input files in place, but the document contains no user-facing warning about possible data exposure, overwrites, or irreversible changes. Under the markdown-specific SQP-2 criterion, the skill description should disclose behaviors that can affect user data, privacy, or system integrity.
The manifest describes reading/extracting content from PDFs, merging/splitting, rotating, watermarking, creating/filling/encrypting PDFs, extracting images from PDFs, and OCR. This script instead renders each PDF page into new PNG image files, which is a distinct PDF-to-image conversion capability not stated in the manifest description.
This PDF helper copies .ttf/.otf files from assets/fonts near the input path or current working directory into user or system font directories, then refreshes font caches. In the context of a form-filling skill, that behavior is unnecessary and dangerous because untrusted PDFs placed alongside attacker-controlled font assets can cause host font installation and persistent modification of the runtime environment beyond the requested document operation.
The script executes an external binary (fc-cache) after copying fonts into writable font directories under the user's home or system font paths. Although it does not invoke a shell, this is still risky behavior for a PDF form-filling utility because it expands scope from document processing into host environment modification and command execution, increasing attack surface and enabling persistence-like side effects if untrusted font assets are present.
if cmd:
try:
import subprocess
subprocess.run([cmd, "-f", str(target_dir)], check=False)
break
except Exception:
pass
This markdown file instructs the user to generate filled PDFs and intermediate JSON files containing form field values, which may include sensitive personal information. The instructions explain how to perform the operation but do not warn that these artifacts will store user data on disk or should be handled carefully.
No suspicious patterns detected.