Back to skill

Security audit

Content News Thai

Security checks for vulnerabilities and agentic risk

Overview

The skill’s Thai social-image purpose is coherent, but it uses broad system setup, privileged font installation, arbitrary URL image loading, and unrestricted file paths that users should review before installing.

Review this skill before installing. Prefer running it in a container or disposable workspace, avoid running setup with elevated privileges unless you accept system package and font changes, pin and verify dependencies and fonts, and do not pass untrusted background image URLs or output paths.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/gen-news.mjs:119
Finding

Unrestricted Background Image Retrieval Enables Server-Side Request Forgery

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/package.json:5
Finding

Mutable npm Dependency Installation Creates a Supply-Chain Risk

Content
View full analysis
package.json << 'EOF' { "name": "content-news-thai", "version": "1.0.0", "type": "module", "dependencies": { "canvas": "^3.1.0" } } EOF fi npm install --production 2>&1 | tail -3 ``` ### Technical Analysis The project declares `canvas` with the mutable version range `^3.1.0` and does not include a reviewed package lockfile. Each setup run can therefore resolve a different compatible package release and a different transitive dependency graph. The setup script uses `npm install`, which may execute package lifecycle scripts. This is especially sensitive for a native module such as `canvas`, which can download or compile native components during installation. The audit found no evidence that the currently declared package is malicious; the vulnerability is the absence of reproducible resolution and integrity-controlled installation. ### Attack Path 1. A future package version or transitive dependency allowed by `^3.1.0` is compromised, maliciously published, or otherwise becomes unsafe. 2. A user follows the documented setup process and runs `scripts/setup.sh`. 3. `npm install --production` resolves the then-current dependency graph because no committed lockfile constrains it. 4. npm downloads the changed components and may execute their lifecycle scripts. 5. Malicious installation behavior runs with the privileges of the user executing setup. ### Impact Assessment A compromised dependency or lifecycle script could execute code with the setup user's privileges. Depending on those privileges, the code could read or m ...[truncated 481 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/setup.sh:65
Finding

Downloaded Font Assets Are Not Integrity-Verified

Content
View full analysis
/dev/null || sudo mkdir -p "$SYSFONT_DIR" cp "$FONTS_DIR"/*.ttf "$SYSFONT_DIR/" 2>/dev/null || sudo cp "$FONTS_DIR"/*.ttf "$SYSFONT_DIR/" fc-cache -f 2>/dev/null || true echo " Fonts installed to $SYSFONT_DIR" fi ``` ### Technical Analysis The setup script downloads fonts from URLs referencing the mutable `main` branch and does not verify cryptographic hashes or signatures. HTTPS protects transport in ordinary conditions but does not establish that the downloaded content matches the exact artifact reviewed by the project. The resulting files are parsed by native font and graphics libraries and copied to a system font directory. A compromised upstream repository, changed branch content, or other supply-chain failure could therefore substitute unexpected or malformed font data. This finding does not indicate that the current Google Fonts files are malicious. It concerns the lack of immutable a ...[truncated 1096 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (15)

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 · scripts/setup.sh (reported line 85)May include surrounding context.

sh
# === 5. Install fonts system-wide (Linux) ===
if [[ "$OS" == "debian" || "$OS" == "linux" ]]; then
  SYSFONT_DIR="/usr/local/share/fonts/thai"
  mkdir -p "$SYSFONT_DIR" 2>/dev/null || sudo mkdir -p "$SYSFONT_DIR"
  cp "$FONTS_DIR"/*.ttf "$SYSFONT_DIR/" 2>/dev/null || sudo cp "$FONTS_DIR"/*.ttf "$SYSFONT_DIR/"
  fc-cache -f 2>/dev/null || true
  echo "   Fonts installed to $SYSFONT_DIR"

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 · scripts/setup.sh (reported line 86)May include surrounding context.

sh
# === 5. Install fonts system-wide (Linux) ===
if [[ "$OS" == "debian" || "$OS" == "linux" ]]; then
  SYSFONT_DIR="/usr/local/share/fonts/thai"
  mkdir -p "$SYSFONT_DIR" 2>/dev/null || sudo mkdir -p "$SYSFONT_DIR"
  cp "$FONTS_DIR"/*.ttf "$SYSFONT_DIR/" 2>/dev/null || sudo cp "$FONTS_DIR"/*.ttf "$SYSFONT_DIR/"
  fc-cache -f 2>/dev/null || true
  echo "   Fonts installed to $SYSFONT_DIR"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs the agent to run shell commands for setup and image generation, but it does not declare any explicit tool scope or allowed-tools boundary. This is dangerous because an agent may invoke shell more broadly than intended, increasing the chance of unintended command execution or abuse if later content or parameters become attacker-controlled.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger phrases are broad and overlap with common user requests like 'make content' or 'news image', which can cause the skill to activate outside a narrowly intended context. Over-broad activation is risky because it may route unrelated requests into a shell-capable skill, unnecessarily exposing execution paths and increasing the attack surface.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file repeatedly frames the skill around generating images with Thai text overlay and Thai-friendly output, but does not state that Thai is optional or user-selected. This can violate language/locale policy when the user has not explicitly opted into Thai output.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script reads any local path supplied in bgImage and writes output to any path supplied in output, with no restriction to a safe workspace directory. In an agent context this can be abused to probe file existence/read sensitive local files as image inputs or overwrite arbitrary writable files, which is broader than the advertised content-generation function and violates least privilege.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script accepts a user-controlled bgImage value and, when it starts with "http", fetches and decodes a remote image. This expands the skill from local image rendering into outbound network access, creating SSRF/privacy and trust-boundary risks if an attacker can supply URLs to internal services or tracking endpoints; image decoders also increase exposure to malformed-image denial-of-service issues.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/setup.sh (reported line 28)May include surrounding context.

sh
apt-get update -qq
  apt-get install -y -qq build-essential libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev librsvg2-dev pkg-config 2>/dev/null || {
    echo "⚠️  apt-get failed — trying without sudo"
    sudo apt-get update -qq
    sudo apt-get install -y -qq build-essential libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev librsvg2-dev pkg-config
  }
elif [[ "$OS" == "macos" ]]; then

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/setup.sh (reported line 29)May include surrounding context.

sh
apt-get update -qq
  apt-get install -y -qq build-essential libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev librsvg2-dev pkg-config 2>/dev/null || {
    echo "⚠️  apt-get failed — trying without sudo"
    sudo apt-get update -qq
    sudo apt-get install -y -qq build-essential libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev librsvg2-dev pkg-config
  }
elif [[ "$OS" == "macos" ]]; then

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The setup script copies downloaded font files into a system-wide directory under /usr/local/share/fonts and may invoke sudo implicitly. That causes privileged modification of the host outside the skill directory, which is risky because externally fetched files are being installed globally and can affect other processes or users on the machine.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
86% confidence
Finding

The script may create a system font directory with sudo as part of an automatic setup path. Because this modifies privileged filesystem locations for a nonessential convenience feature, it broadens the blast radius of running the skill and can normalize elevation without clear consent.

Content

Scanner excerpt · scripts/setup.sh (reported line 85)May include surrounding context.

sh
# === 5. Install fonts system-wide (Linux) ===
if [[ "$OS" == "debian" || "$OS" == "linux" ]]; then
  SYSFONT_DIR="/usr/local/share/fonts/thai"
  mkdir -p "$SYSFONT_DIR" 2>/dev/null || sudo mkdir -p "$SYSFONT_DIR"
  cp "$FONTS_DIR"/*.ttf "$SYSFONT_DIR/" 2>/dev/null || sudo cp "$FONTS_DIR"/*.ttf "$SYSFONT_DIR/"
  fc-cache -f 2>/dev/null || true
  echo "   Fonts installed to $SYSFONT_DIR"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
90% confidence
Finding

The script may copy downloaded TTF files into a privileged system directory using sudo. Installing externally retrieved files system-wide increases supply-chain risk and persists changes beyond the skill itself, making compromise or mistakes more impactful than local-only asset use.

Content

Scanner excerpt · scripts/setup.sh (reported line 86)May include surrounding context.

sh
if [[ "$OS" == "debian" || "$OS" == "linux" ]]; then
  SYSFONT_DIR="/usr/local/share/fonts/thai"
  mkdir -p "$SYSFONT_DIR" 2>/dev/null || sudo mkdir -p "$SYSFONT_DIR"
  cp "$FONTS_DIR"/*.ttf "$SYSFONT_DIR/" 2>/dev/null || sudo cp "$FONTS_DIR"/*.ttf "$SYSFONT_DIR/"
  fc-cache -f 2>/dev/null || true
  echo "   Fonts installed to $SYSFONT_DIR"
fi

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
89% confidence
Finding

The dependency uses a caret range (^3.1.0) rather than an exact pinned version, which makes builds non-reproducible and can silently pull newer releases. In a security-sensitive supply chain context, this increases exposure to unexpected regressions or malicious/compromised upstream updates, even though package.json by itself does not prove active exploitation.

Content

Scanner excerpt · scripts/package.json (reported line 6)May include surrounding context.

json
"version": "1.0.0",
  "type": "module",
  "dependencies": {
    "canvas": "^3.1.0"
  }
}

Unverifiable Dependency: canvas has 2 known advisory(ies) (CVE-2020-8215 (Buffer overflow in canvas); GHSA-vpq5-4rc8-c222 (Denial of Service in canvas)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
82% confidence
Finding

The manifest references canvas without pinning an exact version, while the package has known historical advisories including memory corruption and denial of service. Because the resolved installed version is not verifiable from this manifest alone, there is a supply-chain risk that a vulnerable release could be installed, which matters more here because the skill processes image/text content and depends on native rendering code.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The setup script uses curl to fetch font files from GitHub, which is a network operation transmitting system request metadata to an external service. Although the script prints that it is downloading fonts, it does not clearly warn the user that it will contact external hosts as part of setup.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.