Back to skill

Security audit

TikTok Packager

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its TikTok slide-generation purpose, but its optional Postiz upload path can send media, captions, and API credentials to an environment-controlled endpoint without validation.

Review before installing if you plan to use Postiz. Leave POSTIZ_BASE_URL unset unless you operate the endpoint, use narrowly scoped Postiz credentials, and do not run --postiz or --postiz-only unless you intend to upload the generated slides and caption. Verify cleanup paths before copying the documented rm -rf troubleshooting command.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
src/node/postiz-upload.mjs:57
Finding

Unvalidated Custom API Endpoint Can Expose Postiz Credentials and Publication Content

Content
View full analysis
controller.abort(), effectiveTimeout); try { const response = await fetch(`${baseUrl}/upload`, { method: "POST", headers: { Authorization: apiKey, }, body: form, signal: controller.signal, }); ``` From `src/node/postiz-create-draft.mjs:21-53`: ```js const baseUrl = normalizeBaseUrl( process.env.POSTIZ_BASE_URL || "https://api.postiz.com/public/v1" ); const apiKey = requireEnv("POSTIZ_API_KEY"); const integrationId = requireEnv("POSTIZ_TIKTOK_INTEGRATION_ID"); if (!Array.isArray(mediaRefs) || mediaRefs.length === 0) { throw new PostizDraftError("postizCreateDraft requires at least one uploaded media reference."); } const payload = { integrationId, caption, media: mediaRefs, privacy_level: "SELF_ONLY", content_posting_method: "UPLOAD", }; const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeoutMs); const response = await fetch(`${baseUrl}/posts`, { method: "POST ...[truncated 3161 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (31)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description promises a substantial content-generation workflow for TikTok-style slideshow assets, but the supplied code chunk contains only an empty package initializer with a docstring. There is no evidence of the declared primary purpose or any supporting functionality. This is a material description-to-behavior mismatch because the code does not implement the advertised capabilities at all.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a broader workflow for generating TikTok-style slideshow assets and captions, with templates and validation. The supplied code chunk only performs a specific post-processing task: reading six preexisting slide PNG files, resizing them, arranging them into a 3-column by 2-row contact sheet, and saving that contact sheet as a PNG. It does not create the slides themselves, produce caption text, manage templates, or implement a substantive validation pipeline. While handling six portrait slides is related to the stated domain, the actual behavior is significantly narrower and does not match the declared primary purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The core rendering behavior matches part of the description: the script deterministically creates 6 portrait PNG slides for TikTok-style use and includes checksum metadata. However, the declared purpose overstates the functionality in several material ways. The code only renders slide images from provided slide strings; it does not generate caption text. It also does not create or manage reusable templates beyond merging a default style with optional spec-provided overrides. Finally, while it validates JSON structure, slide count/content, colors, and font path, there is no separate or comprehensive 'strict validation pipeline' as described. Therefore the description is only partially accurate and should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The code chunk is narrowly focused on validating already-rendered slide PNG outputs. It reads a user-supplied directory, checks for exactly six expected filenames, and verifies image dimensions. This aligns only with the 'strict validation pipeline' portion of the description. It does not generate slideshow images, create captions, or implement reusable templates or a posting workflow. Because the declared purpose describes a generator-plus-captioning workflow while the actual code is only a verifier, the description does not accurately represent this code chunk's primary behavior.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- The caption template in `src/node/write-caption.mjs`

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
93% confidence
Finding

The documented rm -rf outbox/_tmp_slides command is a destructive operation that can be dangerous if the path is mistyped, interpolated, or reused in automation. In an agent skill context, such instructions may be copied into scripts or executed by tooling, increasing the chance of unintended deletion beyond the temporary render directory.

Content

Scanner excerpt · references/troubleshooting.md (reported line 40)May include surrounding context.

If filenames or dimensions mismatch, delete stale outputs and regenerate:

bash
rm -rf outbox/_tmp_slides
python3 scripts/render_slides_pillow.py --spec examples/sample-slide-spec.json --out outbox/_tmp_slides --font /absolute/path/to/font.ttf
python3 scripts/verify_slides.py --dir outbox/_tmp_slides

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This function creates remote Postiz/TikTok drafts by sending captions and media references to an external API, which materially exceeds the skill's declared purpose of generating local slideshow assets and caption text. In an agent-skill context, this creates an undeclared outbound action path that can publish or stage user content on a third-party platform, increasing the risk of unauthorized data transmission and social-account abuse.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code performs external social-post draft creation through a third-party API despite the skill being described only as an asset and caption generator. That mismatch is dangerous because users or orchestrators may grant the skill access expecting local-only processing, while it actually transmits content externally and can manipulate connected social integrations.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

This module reads a local file and uploads it to an external Postiz API, which exceeds the stated scope of a skill described as generating local slideshow assets and caption text. That scope mismatch creates a real data exfiltration risk because generated or user-provided media leaves the local environment and is sent to a third party without clear justification in the skill description.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill advertises executable workflows using Node, Python, local file output, and optional upload behavior, but it does not declare any explicit tool or permission scope. In an agent environment, missing scope boundaries can cause the runtime to grant broader shell, file read, and file write access than users expect, increasing the chance of unsafe execution or unintended filesystem effects.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

The skill supports optional transmission to an external service endpoint (Postiz), which creates a real data egress path for generated content, metadata, and potentially account-linked identifiers. In agent contexts, external upload capability is security-relevant because it can move data off-host or off-platform if enabled without clear consent and scoped controls.

Content

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

md
Optional:

- `POSTIZ_BASE_URL` (defaults to `https://api.postiz.com/public/v1`)
- `TIKTOK_FONT_PATH` (absolute `.ttf` path)

## References

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The setup instructions ask for POSTIZ_BASE_URL, POSTIZ_API_KEY, and POSTIZ_TIKTOK_INTEGRATION_ID, and later document upload/resume flows. For a skill whose stated purpose is generating slideshow assets and captions, handling third-party API credentials and upload orchestration is not an obvious or necessary capability.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes the skill as generating deterministic slideshow PNG assets and caption text with templates and validation. This setup file documents a --postiz mode using API credentials and an integration ID to perform upload/resume actions, which is a materially broader behavior than local asset generation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The troubleshooting guide tells users to run a recursive deletion command without any warning, path validation, or safer alternative. Even though the target path is relatively narrow, destructive shell commands in documentation can lead to accidental data loss if copied, modified, or run from the wrong context.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · src/node/hashtags/policy.mjs (reported line 14)May include surrounding context.

js
},
};

const TOKEN_STOPLIST = new Set([
  "the",
  "and",
  "for",

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · src/node/hashtags/policy.mjs (reported line 45)May include surrounding context.

js
},
};

const TOKEN_STOPLIST = new Set([
  "the",
  "and",
  "for",

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

This code sends data to an external service endpoint at api.postiz.com, including caption text, media references, and integration identifiers. External transmission is not inherently malicious, but in this skill context it is risk-relevant because the advertised functionality is local asset generation, so the network egress is unexpected and can expose user content or trigger downstream actions on linked accounts.

Content

Scanner excerpt · src/node/postiz-create-draft.mjs (reported line 22)May include surrounding context.

js
idempotencyKey,
}) {
  const baseUrl = normalizeBaseUrl(
    process.env.POSTIZ_BASE_URL || "https://api.postiz.com/public/v1"
  );
  const apiKey = requireEnv("POSTIZ_API_KEY");
  const integrationId = requireEnv("POSTIZ_TIKTOK_INTEGRATION_ID");

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code retrieves an API key from environment variables and uses it to authenticate a remote upload of local file contents. Even if the credential itself is handled conventionally, combining hidden credential use with an undeclared network action expands the skill's authority beyond its stated purpose and can enable unauthorized publication or transfer of sensitive media.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

The hardcoded default external endpoint to api.postiz.com confirms that this file performs third-party transmission. An external endpoint is not inherently malicious, but in this skill context it is security-relevant because the advertised functionality emphasizes local generation rather than remote delivery, making undisclosed outbound transfer more dangerous.

Content

Scanner excerpt · src/node/postiz-upload.mjs (reported line 58)May include surrounding context.

js
maxAttempts = 3,
}) {
  const baseUrl = normalizeBaseUrl(
    process.env.POSTIZ_BASE_URL || "https://api.postiz.com/public/v1"
  );
  const apiKey = requireEnv("POSTIZ_API_KEY");

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The function transmits the full local file buffer over the network with no evidence of any user-facing disclosure, confirmation, or policy check. In a skill marketed around deterministic local asset generation, silent upload materially increases privacy and trust risk because users may reasonably assume outputs remain local.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The stated purpose is generating slideshow assets and captions with validation, but this implementation additionally spawns python3 subprocesses to run local scripts. Subprocess execution is a broader capability than expected from a content-generation skill and is not justified by the manifest text itself.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file goes beyond local asset generation and can transmit generated media and captions to the remote Postiz service via upload and draft-creation calls. In a skill advertised primarily as producing deterministic slideshow assets and captions, this broadens the trust boundary and creates privacy/data-exfiltration risk if users run it with real or sensitive content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code uploads generated slide images and caption text to Postiz whenever the relevant flags are set, but there is no interactive warning or confirmation at the moment data leaves the system. This can cause accidental disclosure of unpublished, proprietary, or sensitive content, especially in automated workflows where operators may not realize remote transmission occurs.

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 · tests/python/test_golden_render.py (reported line 50)May include surrounding context.

python
"--font",
                    str(font),
                ]
                subprocess.run(cmd, check=True)
                cmd[5] = str(out_b)
                subprocess.run(cmd, check=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 · tests/python/test_golden_render.py (reported line 52)May include surrounding context.

python
"--font",
                    str(font),
                ]
                subprocess.run(cmd, check=True)
                cmd[5] = str(out_b)
                subprocess.run(cmd, check=True)

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/pack-skill.mjs:13

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/release.mjs:33

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/node/render-slides.mjs:29

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/node/tiktok-intro-draft.mjs:46

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/node/postiz-create-draft.mjs:22

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/node/postiz-upload.mjs:58