Back to skill

Security audit

pdf-online

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its document-publishing purpose, but its spreadsheet image workflows can fetch arbitrary URLs from parsed content and upload the results to cloud workbooks.

Review before installing. Use this skill only with trusted documents and trusted SoMark Markdown/JSON, and avoid spreadsheet imports containing untrusted image URLs until the Feishu and DingTalk image downloaders restrict requests to public or allowlisted hosts. Expect it to create and modify cloud documents, sheets, Bases, or Notion pages using your authenticated platform tools, and clean up local output directories if the parsed content is sensitive.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
platforms/dingtalk/scripts/somark_dingtalk/sheet_route.py:44
Finding

DingTalk Spreadsheet Image Processing Allows SSRF and Internal Data Upload

Content
View full analysis
bool: parsed = urlparse(value.strip()) return parsed.scheme.casefold() in {"http", "https"} and bool(parsed.netloc) ``` Image references are derived from table content in the supplied SoMark JSON: ```python references = list(source.image_references) references.extend( (match.group(1), None, None) for match in _MARKDOWN_IMAGE_RE.finditer(source.text) ) seen_refs: set[str] = set() for reference, width_px, height_px in references: if reference in seen_refs: continue seen_refs.add(reference) images.append( ImagePlan( cell=cell, source_reference=reference, local_path=_local_asset(reference, assets), width=width_px, height=height_px, ) ) ``` The downloader follows the supplied URL without private-network or redirect-destination validation: ```python def download_remote_image( reference: str, destination_dir: Path, *, timeout: float = 30.0, max_bytes: int = _MAX_IMAGE_BYTES, ) -> Path: """Materialize one SoMark table-image URL after the preview is ready.""" if not is_remote_image_reference(reference): raise ValueError("image reference is not an HTTP(S) URL") parsed = urlparse(reference.strip()) if parsed.username or parsed.password: raise ValueError("image URL must not contain credentials") request = Request(reference, headers={"User-Agent": "SoMark-DingTalk-Adapter/1"}) destin ...[truncated 4842 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
platforms/feishu/scripts/apply_sheets_payload.py:62
Finding

Feishu Sheets Image Enhancement Allows SSRF and Internal Data Upload

Content
View full analysis
Path: """Download one SoMark image URL for the post-preview image stage.""" parsed = urlparse(reference.strip()) if parsed.scheme.casefold() not in {"http", "https"} or not parsed.netloc: raise ValueError("image reference is not an HTTP(S) URL") if parsed.username or parsed.password: raise ValueError("image URL must not contain credentials") request = Request(reference, headers={"User-Agent": "SoMark-Feishu-Adapter/1"}) destination_dir.mkdir(parents=True, exist_ok=True) with urlopen(request, timeout=timeout) as ...[truncated 5820 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This code chunk does not implement the declared end-user function of parsing files with SoMark and publishing results to collaboration platforms. Instead, it is low-level execution infrastructure for running a dws command safely and deterministically. While such a runner could be a supporting component within a larger DingTalk integration, the supplied chunk’s actual behavior is materially different from the declared purpose and introduces an undeclared capability: invoking a local CLI subprocess. No file parsing, SoMark conversion, or Feishu/DingTalk/Notion publishing logic appears in this snippet.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The supplied code chunk is a persistence utility for route manifests. It defines schema/version checks, stage transitions, validation rules, atomic JSON writes, and manifest reads. This is an implementation focused on recording workflow metadata and errors on disk, with redaction support. The declared purpose, however, centers on document parsing and cross-platform publishing/importing. Those behaviors are absent from this code chunk. While manifest handling could be a supporting detail inside a larger publishing system, this specific chunk's actual behavior is materially different from the declared end-user functionality, so it should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared description is broader than the supplied code. The code is narrowly scoped to DingTalk (somark_dingtalk) and orchestrates route execution for document/sheet/AI table targets using explicit SoMark artifacts. In _prepare_artifacts, it raises an error stating that DingTalk publishing requires the exact Markdown and JSON artifacts and that source-only publishing is not supported, so it does not perform the advertised file parsing from PDF/image/Word/PPT in this chunk. The code also contains no Feishu or Notion publishing logic. Additionally, it provides manifest persistence, event emission, and resume() logic to continue deferred work without recreating targets, which is meaningful behavior absent from the declared description. Therefore the description does not accurately represent what this specific code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The description presents a broad multi-platform document-import skill centered on parsing source files with SoMark and publishing them to several platforms and content types. The supplied code chunk is only a platform-specific DingTalk sheet executor. Its primary behavior is workbook/worksheet creation and spreadsheet population with rigorous readback verification and post-processing. That narrower scope is not inherently a problem in a modular system, but this chunk also includes an undeclared capability: fetching remote images over HTTP(S) before uploading them into DingTalk sheets. Since the declared purpose does not mention external URL downloads and the chunk does not perform the advertised parsing or multi-platform publishing itself, the description does not accurately represent this code chunk's actual behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code chunk is narrowly focused on deploying an already-prepared spreadsheet payload to Feishu/Lark Sheets. It does not parse source files, does not handle Markdown/JSON import across multiple platforms, and does not interact with DingTalk or Notion. While this could be a supporting component of the broader declared workflow, the actual behavior in this chunk is materially narrower and includes an undeclared capability of fetching remote images over HTTP(S). Therefore the declared description does not accurately represent what this specific code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description claims an end-to-end ingestion and publishing capability across multiple platforms. This code chunk is narrower: it is a local transformation utility specifically for Feishu. It reads a Markdown file and optional JSON, normalizes/rewrites Markdown constructs (tables, formulas, images, code fences, structural elements), builds audit/post-import metadata, and writes output files. There are no API calls, network operations, authentication flows, or document creation calls for Feishu, DingTalk, or Notion. There is also no file parsing of PDFs, images, Word, or PPT via SoMark in this chunk. Therefore the declared description materially overstates both scope and primary behavior relative to the supplied code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description presents a broad document-import and publishing skill across several platforms and output formats. This code chunk is much narrower: it is a Feishu-specific adapter for table data, using SoMark JSON as input and lark-cli to create a Base and append records. It prepares mappings, infers field types, validates payloads, creates Feishu Base schema, and uploads records in batches. There is no code here for parsing PDF/image/Word/PPT, no support for DingTalk or Notion, no handling of editable documents or spreadsheets outside Bitable, and no Markdown+JSON pair import. These are material scope differences affecting the skill's represented capabilities, so the description does not accurately match this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description promises a broad, end-to-end cross-platform conversion and publishing capability. The supplied code chunk is much narrower: it is a local planning utility for Notion databases only. It consumes already-produced SoMark JSON, parses HTML table content within that JSON, infers schema/types, assesses suitability, validates a plan, and writes database_plan.json. There is no code for file parsing via SoMark, no support for Feishu or DingTalk, no API calls or publication step, and no Markdown import path. This is a material description-behavior mismatch, not merely an implementation detail.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description describes an end-to-end ingestion and publishing skill across multiple platforms. The supplied code is a narrow offline transformer: it reads a SoMark JSON structure from disk, validates and converts supported block types into Notion Markdown, generates a manifest, and writes those files locally. There is no code for parsing PDFs/images/Word/PPT, no network calls, no SDK/API usage for Notion/Feishu/DingTalk, and no cross-platform publishing behavior. While the code is related to one slice of the stated workflow (preparing Notion-formatted output from SoMark JSON), it materially underimplements and differs from the declared primary capability set, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents a broad cross-platform document ingestion and publishing capability: taking various file types or exact SoMark outputs and importing them into Feishu, DingTalk, or Notion. The supplied code chunk does something much narrower and different in primary purpose: it validates and transforms an already-prepared Notion database plan into an ASCII-only MCP payload for batched database submission. This is related to one slice of the overall domain (Notion database import), but it does not implement file parsing, general SoMark conversion, or multi-platform publishing. Because the code’s actual scope is materially narrower and focused on Notion database payload emission from prevalidated JSON plans, the description does not accurately represent this specific code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents a broad document-ingestion and publishing skill for multiple platforms. This code chunk instead is a narrow utility for Notion only: it reads manifest/page files from two directories, compares baseline and enhanced table HTML/markdown, validates that only merge-related table changes occurred, and emits a JSON payload describing string replacements to apply to current Notion page content. It neither parses source files nor communicates with Feishu, DingTalk, or Notion APIs. This is a materially different primary purpose, so the description does not accurately represent the code.

Content

No source excerpt is available for this finding.

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 · platforms/feishu/scripts/apply_feishu_blocks.py (reported line 89)May include surrounding context.

python
def _run_lark(arguments: list[str], body: dict[str, Any] | None = None) -> Any:
    environment = os.environ.copy()
    environment["LARKSUITE_CLI_NO_UPDATE_NOTIFIER"] = "1"
    environment["LARKSUITE_CLI_NO_SKILLS_NOTIFIER"] = "1"
    completed = subprocess.run(

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares no explicit tool scope even though its behavior routes into platform modules that can plausibly use filesystem, network, shell, and environment access. In an agent setting, missing scope boundaries increases the chance of over-privileged execution and makes downstream adapter behavior harder to audit or constrain.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code performs real remote side effects against DingTalk, including document creation and subsequent block updates, when execute=True, but it does not enforce an explicit user-confirmation or warning step at the point of execution. In an agent skill that can be triggered from user content or higher-level orchestration, that creates a meaningful risk of unintended publication or modification of remote documents, especially because resume and post-processing paths can continue writes after the initial create.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
76% confidence
Finding

The manifest describes parsing files with SoMark and publishing results to collaboration platforms, but this module adds a general subprocess execution layer for an external CLI. While it is constrained to the dws binary and uses safety checks, spawning a local executable is a stronger capability than the manifest explicitly states and is not obviously required from the description alone.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill explicitly instructs the agent to perform a remote Feishu Drive import immediately and later to continue enhancement/API writes without pausing for user confirmation. That creates a real external-write risk: a user may intend conversion or preview only, while the agent autonomously uploads potentially sensitive document content to a third-party service and performs additional mutations after the initial import.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
84% confidence
Finding

The instruction to avoid asking the user to confirm headers, field mapping, or destination details before parsing and preparing Bitable actions increases autonomous decision-making over structured data creation. In context, this can cause the agent to infer schema and proceed toward creating records/bases based on imperfect OCR/SoMark output, which risks unintended writes, incorrect field mapping, and leakage of sensitive table data into Feishu.

Content

Scanner excerpt · platforms/feishu/SKILL.md (reported line 314)May include surrounding context.

md
existing Base or supplies a Base URL/token as the destination. Do not reuse a
recent Base merely because it is available.

Do not ask the user to confirm headers, field mapping, or a destination Base
before SoMark parsing. After a successful SoMark JSON result exists, treat its
HTML `table.content` as the sole source of truth for Bitable headers. Never
open, render, screenshot, visually inspect, or run another OCR pass on the

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 · platforms/feishu/scripts/apply_feishu_blocks.py (reported line 92)May include surrounding context.

python
environment = os.environ.copy()
    environment["LARKSUITE_CLI_NO_UPDATE_NOTIFIER"] = "1"
    environment["LARKSUITE_CLI_NO_SKILLS_NOTIFIER"] = "1"
    completed = subprocess.run(
        [*_lark_command(), *arguments],
        input=json.dumps(body, ensure_ascii=False) if body is not None else None,
        capture_output=True,

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 · platforms/feishu/scripts/apply_sheets_payload.py (reported line 157)May include surrounding context.

python
) -> dict[str, Any]:
    attempt = 0
    while True:
        completed = subprocess.run(
            [cli, *args],
            cwd=cwd,
            capture_output=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The script writes prepared payloads containing parsed table rows from source documents to disk as JSON, and this data may include sensitive business or personal information extracted from PDFs, images, Word files, or PPTs. In this skill’s context, local persistence is operationally useful for audit/retry, but the lack of explicit disclosure or opt-in increases the risk of unintentional retention, exposure to other local users/processes, or inclusion in backups and logs.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The docstring claims deterministic behavior, yet resolve_executable() uses shutil.which("dws") and then runs whatever matching binary is found on PATH. That means behavior can vary across environments or be influenced by PATH contents, so the documentation overstates determinism and safety guarantees.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The generated footnote text is hardcoded as "尾注" in a user-visible output string, and the script also emits other user-facing text in Chinese later in the file. Because this is a general conversion utility rather than a clearly region-specific tool, forcing one locale in generated content can violate language/locale policy when no user opt-in or configuration is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
74% confidence
Finding

The post-import metadata hardcodes the representation name "numbered_endnote_blockquote" based on content that is rendered with Chinese numbering text elsewhere, while the tool provides no locale selection. This suggests the conversion behavior assumes a specific language environment instead of allowing user choice or documenting a justified locale restriction.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The help string says that if --asset-dir is omitted, an enhancement stage will download HTTP(S) image URLs from SoMark JSON table cells. In this file, image handling is limited to indexing local assets, matching URLs to local files, and embedding URL text into cells; there are no HTTP clients, network calls, or download logic.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The user-facing argparse help string is written only in Chinese, which imposes a specific language on users of this script. The file does not offer a language choice or document that the tool is intentionally limited to a Chinese-speaking or region-specific audience.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.