Back to skill

Security audit

Korean Gov Programs

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated scraping purpose, but one bundled status script has a real local code-execution risk when given a crafted data directory path.

Review before installing or running. The collector appears to scrape public program listings and write local JSONL/checkpoint files, but avoid passing untrusted or attacker-controlled paths to scripts/stats.sh until that script is fixed to pass the checkpoint path as data rather than interpolating it into python3 -c. Expect outbound requests to Korean government/program listing sites and local writes under the chosen output directory.

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

Error
Location
scripts/stats.sh:82
Finding

Python Code Injection Through a User-Controlled Data Directory

Content
View full analysis

Vulnerability Details

File Location: scripts/stats.sh, lines 82–94
Vulnerability Type: Python source-code injection
Risk Level: High

Vulnerable Code

bash
CHECKPOINT="$DATA_DIR/.checkpoint.json"
if [[ -f "$CHECKPOINT" ]]; then
  echo ""
  echo "📍 체크포인트:"
  python3 -c "
import json
with open('$CHECKPOINT', encoding='utf-8') as f:
    cp = json.load(f)
for k, v in cp.items():
    print(f'  {k}: {v}')
"
fi

DATA_DIR is initialized from the first command-line argument earlier in the script:

bash
DATA_DIR="${1:-./data}"

Technical Analysis

The user-controlled DATA_DIR value is used to construct CHECKPOINT, which is then interpolated directly into Python source passed to python3 -c.

Shell quoting does not make this safe at the Python-language layer. A checkpoint path containing a single quote, line break, or other Python syntax can terminate the string literal in with open('$CHECKPOINT', ...) and inject additional Python statements.

The [[ -f "$CHECKPOINT" ]] check does not sanitize the path. An attacker who controls the argument and can prepare a matching crafted filesystem path can satisfy that check before the vulnerable Python command is evaluated.

Attack Path

  1. An attacker chooses a malicious data-directory name containing characters that terminate the single-quoted Python path literal and introduce attacker-controlled Python statements.
  2. The attacker creates the crafted directory structure and a corresponding .checkpoint.json path so that [[ -f "$CHECKPOINT" ]] succeeds.
  3. The victim or an automated process invokes:
    bash
    bash scripts/stats.sh "$ATTACKER_CONTROLLED_DIRECTORY"
    
  4. The shell expands $CHECKPOINT into the source-code string supplied to python3 -c.
  5. Python parses the injected content as executable source rather than as path data.
  6. The injected Python statements execute with the privilege ...[truncated 715 chars]
Remediation
View remediation

Remediation Suggestions

Do not embed filesystem paths or other external values into source code. Pass the checkpoint path as a positional argument and read it from sys.argv:

bash
CHECKPOINT="$DATA_DIR/.checkpoint.json"
if [[ -f "$CHECKPOINT" ]]; then
  echo ""
  echo "Checkpoint:"
  python3 - "$CHECKPOINT" <<'PYEOF'
import json
import sys

checkpoint = sys.argv[1]
with open(checkpoint, encoding="utf-8") as f:
    cp = json.load(f)

for key, value in cp.items():
    print(f"  {key}: {value}")
PYEOF
fi

This keeps the path as data throughout execution and prevents it from changing the Python program's syntax.

Additional hardening should include:

  • Preserve the quoted shell argument "$CHECKPOINT".
  • Avoid constructing interpreter programs with shell-expanded input.
  • Reject unexpected file types and consider resolving the path before use if the caller should be restricted to a designated data root.
  • Run the script with the minimum required filesystem permissions.
  • Add a regression test using directory names containing single quotes, spaces, newlines, and Python metacharacters.
Vulnerability Patterns
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (6)

Tainted flow: 'req' from os.environ.get (line 94, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/collect.py (reported line 95)May include surrounding context.

python
"""urllib.request만 사용 (requests 라이브러리 미사용)"""
    try:
        req = urllib.request.Request(url, headers=HEADERS)
        with urllib.request.urlopen(req, timeout=timeout) as resp:
            charset = resp.headers.get_content_charset() or "utf-8"
            return resp.read().decode(charset, errors="replace")
    except Exception as e:

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documentation describes a narrower and somewhat different collection scope than the behavior implied by the rest of the skill, including unsupported TIPS coverage and additional sources like NIA/KISED. This mismatch can mislead users and security reviewers about what data is actually collected, what sites are contacted, and what operational assumptions are safe, which weakens trust and can mask unexpected network behavior.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill declares executable behavior that can use environment access, file writes, and network access, but it does not declare any explicit tool scope or permissions boundary. In an agent setting, this creates an authorization and transparency gap: operators cannot easily constrain what the skill may access, and the skill could be run with broader capabilities than intended.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill description and usage documentation are written entirely in Korean, which effectively imposes a specific language on users. The file does not offer an opt-in language choice or explain that the skill is intentionally restricted to Korean-speaking users for a documented compliance or regional reason.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The HTTP headers hard-code Accept-Language to prefer ko-KR, and the script description and user-facing logs are entirely Korean. This imposes a specific language/locale behavior without any documented opt-in or alternative, which matches the language/locale policy violation category.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

This shell script presents its title, usage guidance, and status messages only in Korean. That creates a natural-language locale restriction without user opt-in or an explicit justification that the skill is intended only for Korean-speaking users.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.