Back to skill

Security audit

Latex To Nextra Site

Security checks for vulnerabilities and agentic risk

Overview

The skill has a legitimate documentation-conversion purpose, but some generated build and diagram-rendering instructions could run unintended local commands or expose build secrets if used on untrusted projects.

Review and adjust the generated scripts before running them on untrusted projects. Replace shell-based execSync docker commands with argument-array execution, validate diagram filenames, pin the PlantUML image by digest, use read-only source mounts and restricted networking where possible, and avoid copying any token-bearing .npmrc into Docker builds.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:346
Finding

Shell Command Injection Through Untrusted Diagram Filenames and Paths

Content
View full analysis
f.endsWith(".puml")).sort(); let ok = 0, fail = 0; for (const file of files) { const figBase = file.replace(/\.puml$/, ""); const firstLine = (await fs.readFile(path.join(srcDir, file), "utf8")).split(/\r?\n/, 1)[0]; const m = firstLine.match(/@startuml\s+(\S+)/); const alias = m ? m[1] : null; try { for (const fmt of ["svg", "png"]) { const cmd = `docker run --rm -v "${srcDir}:/data" -v "${outDir}:/out" ` + `plantuml/plantuml:latest -charset UTF-8 -output /out -t${fmt} /data/${file}`; execSync(cmd, { stdio: ["ignore", "ignore", "pipe"], windowsHide: true }); } const baseName = alias || figBase; if (baseName !== figBase) { try { await fs.copyFile(path.join(outDir, baseName + ".svg"), path.join(outDir, figBase + ".svg")); } catch {} try { await fs.copyFile(path.join(outDir, baseName + ".png"), path.join(outDir, figBase + ".png")); } catch {} } ok++; } catch (e) { fail++; } } ``` ### Technical Analysis The generated rendering script enumerates `.puml` files and inserts each filename directly into a command string passed to `execSync()`. In Node.js, passing a string to `execSync()` causes the command to be interpreted by a system shell. The `file` value is derived from the input project and is neither validated nor encoded as a shell argument. A filename containing shell metacharacters can therefore alter the command ...[truncated 2017 chars]
Remediation
View remediation
", "-charset", "UTF-8", "-output", "/out", `-t${fmt}`, `/data/${file}`, ]; execFileSync("docker", args, { stdio: ["ignore", "ignore", "pipe"], windowsHide: true, shell: false, }); ``` 2. Validate input filenames before execution. Reject path separators, control characters, null bytes, shell metacharacters, and filenames outside a conservative allowlist. 3. Verify that each resolved input remains under `srcDir`: ```js const inputPath = path.resolve(srcDir, file); const relative = path.relative(srcDir, inputPath); if (relative.startsWith("..") || path.isAbsolute(relative)) { throw new Error(`Invalid diagram path: ${file}`); } ``` 4. Do not attempt to solve the issue through manual quoting alone. Correct escaping varies across POSIX shells, PowerShell, and `cmd.exe`. 5. Run conversion in a sandbox with minimal filesystem access, no unnecessary secrets, restricted network access, and narrowly scoped Docker permissions. 6. Apply the correction to both `SKILL.md` and `SKILL.zh-CN.md` so that generated implementations remain consistent. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:228
Finding

Mutable Container Image and Unpinned Package Dependencies

Content
View full analysis
-site", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "prepare:content": "node scripts/tex2mdx.mjs && node scripts/build-meta.mjs && node scripts/renumber-content.mjs", "prepare:diagrams": "node scripts/render-plantuml.mjs && node scripts/export-drawio.mjs", "convert": "npm run prepare:diagrams && npm run prepare:content" }, "dependencies": { "next": "^14.2.15", "nextra": "^3.2.4", "nextra-theme-docs": "^3.2.4", "react": "^18.3.1", "react-dom": "^18.3.1" }, "devDependencies": { "@types/node": "^20.12.12", "@types/react": "^18.3.3", "typescript": "^5.4.5" }, "engines": { "node": ">=18.17.0" } } ``` The diagram renderer executes a mutable `latest` image: ```js for (const fmt of ["svg", "png"]) { const cmd = `docker run --rm -v "${srcDir}:/data" -v "${outDir}:/out" ` + `plantuml/plantuml:latest -charset UTF-8 -output /out -t${fmt} /data/${file}`; execSync(cmd, { stdio: ["ignore", "ignore", "pipe"], windowsHide: true }); } ``` ### Technical Analysis The Skill states that remote resources should be pinned to release tags, but its implementation uses `plantuml/plantuml:latest`. The `latest` tag is mutable and can resolve to different image content without any change to the reviewed Skill. The npm manifest also uses caret version ranges. These allow later compatible releases to be selected when a lockfile is absent or regenerated. Although a committed lockfile and `npm ci` can constrain npm resolution after initial generation, the example does not establish im ...[truncated 1952 chars]
Remediation
View remediation
``` 2. Record the human-readable release version and digest together so maintainers can intentionally review and update the image. 3. Replace npm caret ranges with exact reviewed versions: ```json { "dependencies": { "next": "14.2.15", "nextra": "3.2.4", "nextra-theme-docs": "3.2.4", "react": "18.3.1", "react-dom": "18.3.1" } } ``` 4. Generate, review, and commit `package-lock.json`. Use `npm ci --ignore-scripts` where lifecycle scripts are unnecessary. If scripts are required, explicitly review the packages that define them before allowing execution. 5. Enable lockfile integrity verification and dependency auditing in CI. Treat lockfile changes as security-sensitive review events. 6. Require explicit user approval before the first network retrieval, as already stated by the Skill's security policy. 7. Restrict container networking when rendering does not need network access, for example with `--network=none`. 8. Mount source diagrams read-only and keep only the output directory writable: ```text -v :/data:ro -v :/out ``` 9. Run builds without unrelated credentials in the environment and ensure local secret files are excluded from both the Docker build context and deployment uploads. 10. Update both language editions so their dependency examples and security policy remain aligned. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (34)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
> **Bilingual note**: This English edition mirrors `SKILL.zh-CN.md`. For the authoritative Chinese version, see `SKILL.zh-CN.md`.

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

The Dockerfile copies .npmrc* into the build context before running npm ci/install. If a user’s .npmrc contains registry auth tokens or other secrets, those credentials may be baked into image layers, exposed in build caches, or inadvertently propagated in CI systems.

Content

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

md
FROM node:18-alpine AS deps
WORKDIR /app
RUN apk add --no-cache libc6-compat
COPY package.json package-lock.json* .npmrc* ./
RUN if [ -f package-lock.json ]; then \
      npm ci --no-audit --no-fund; \
    else \

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
├── .dockerignore
├── package.json
├── package-lock.json
├── .npmrc
├── next.config.mjs             # Nextra + i18n + KaTeX + standalone
├── theme.config.tsx            # Logo、暗黑模式、搜索、页脚
├── middleware.js               # / → /zh 重定向(必需)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
├── .dockerignore
├── package.json
├── package-lock.json
├── .npmrc
├── next.config.mjs             # Nextra + i18n + KaTeX + standalone
├── theme.config.tsx            # Logo、暗黑模式、搜索、页脚
├── middleware.js               # / → /zh 重定向(必需)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
├── .dockerignore
├── package.json
├── package-lock.json
├── .npmrc
├── next.config.mjs             # Nextra + i18n + KaTeX + standalone
├── theme.config.tsx            # Logo、暗黑模式、搜索、页脚
├── middleware.js               # / → /zh 重定向(必需)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
├── .dockerignore
├── package.json
├── package-lock.json
├── .npmrc
├── next.config.mjs             # Nextra + i18n + KaTeX + standalone
├── theme.config.tsx            # Logo、暗黑模式、搜索、页脚
├── middleware.js               # / → /zh 重定向(必需)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
├── .dockerignore
├── package.json
├── package-lock.json
├── .npmrc
├── next.config.mjs             # Nextra + i18n + KaTeX + standalone
├── theme.config.tsx            # Logo、暗黑模式、搜索、页脚
├── middleware.js               # / → /zh 重定向(必需)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.zh-CN.md (reported line 120)May include surrounding context.

md
├── .dockerignore
├── package.json
├── package-lock.json
├── .npmrc
├── next.config.mjs             # Nextra + i18n + KaTeX + standalone
├── theme.config.tsx            # Logo、暗黑模式、搜索、页脚
├── middleware.js               # / → /zh 重定向(必需)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.zh-CN.md (reported line 293)May include surrounding context.

md
├── .dockerignore
├── package.json
├── package-lock.json
├── .npmrc
├── next.config.mjs             # Nextra + i18n + KaTeX + standalone
├── theme.config.tsx            # Logo、暗黑模式、搜索、页脚
├── middleware.js               # / → /zh 重定向(必需)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.zh-CN.md (reported line 301)May include surrounding context.

md
├── .dockerignore
├── package.json
├── package-lock.json
├── .npmrc
├── next.config.mjs             # Nextra + i18n + KaTeX + standalone
├── theme.config.tsx            # Logo、暗黑模式、搜索、页脚
├── middleware.js               # / → /zh 重定向(必需)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.zh-CN.md (reported line 920)May include surrounding context.

md
├── .dockerignore
├── package.json
├── package-lock.json
├── .npmrc
├── next.config.mjs             # Nextra + i18n + KaTeX + standalone
├── theme.config.tsx            # Logo、暗黑模式、搜索、页脚
├── middleware.js               # / → /zh 重定向(必需)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.zh-CN.md (reported line 921)May include surrounding context.

md
├── .dockerignore
├── package.json
├── package-lock.json
├── .npmrc
├── next.config.mjs             # Nextra + i18n + KaTeX + standalone
├── theme.config.tsx            # Logo、暗黑模式、搜索、页脚
├── middleware.js               # / → /zh 重定向(必需)

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The Dockerfile copies .npmrc* into the build context for dependency installation. In many real environments .npmrc may contain private registry credentials or auth tokens, so copying it into image layers risks secret exposure through build cache, intermediate images, logs, or accidental publication.

Content

Scanner excerpt · SKILL.zh-CN.md (reported line 680)May include surrounding context.

md
FROM node:18-alpine AS deps
WORKDIR /app
RUN apk add --no-cache libc6-compat
COPY package.json package-lock.json* .npmrc* ./
RUN if [ -f package-lock.json ]; then \
      npm ci --no-audit --no-fund; \
    else \

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The document states a language policy of defaulting to Chinese as the primary language and only generating English as a placeholder skeleton. This is a natural-language locale policy constraint that is imposed by the skill itself rather than presented as an explicit user choice, which can conflict with organizational expectations around user language/locale neutrality.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

The documented command uses a floating Docker tag (plantuml/plantuml:latest) when rendering untrusted diagram inputs. A mutable tag can silently change over time, undermining reproducibility and exposing users to supply-chain risk if the upstream image is compromised or updated unexpectedly.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding

This line explicitly recommends docker run plantuml/plantuml:latest, which relies on a mutable tag. In a build/conversion skill that may be reused frequently, this increases supply-chain exposure and makes output non-reproducible across runs.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding

This is another recommendation to directly run plantuml/plantuml:latest. Because the skill processes user-provided content and encourages container execution, using a mutable image reference creates avoidable supply-chain risk and inconsistent behavior over time.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding

This example again recommends docker run plantuml/plantuml:latest, a mutable image tag. Repeated inclusion across the skill increases the chance users will follow the unsafe pattern, amplifying supply-chain and reproducibility concerns.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

文档在语言策略中明确规定“默认中文(zh)为主语言”,并要求同步生成英文占位骨架。这种默认语言强制本身未必有害,但结合后文的根路径自动跳转,会导致用户在未被询问语言偏好的情况下进入特定语言版本。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

质量闸门将“首页 / 自动重定向到 /zh”列为必须项,属于明确的语言/locale 强制行为。根据规则,若技能强制特定语言而没有提供用户选择或充分的范围说明,应视为自然语言政策违规。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

这里不仅在说明层面要求重定向,而且给出了实际硬编码到 /zh 的实现。这使技能生成的站点默认强制中文 locale,且没有展示任何按用户偏好切换默认入口的机制。

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
98% confidence
Finding

The script invokes the container image plantuml/plantuml:latest, which is mutable and can change over time. Using latest in an automated conversion workflow creates supply-chain risk: a compromised or incompatible upstream image could silently alter outputs or execute attacker-controlled code during rendering.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

该段再次强调 pages/zh/ 为事实标准内容源,并要求 middleware.js 自动跳转 /zh,同时把 zh 排在 i18n 首位。这属于跨文档一致的语言强制策略,但缺少用户 opt-in 或明确限定仅服务中文场景的说明。

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.