Versioned security assessment

Report ID: SA-A4878B3A

7/5/2026, 9:16:16 PM

ckm-design security assessment v3

Skill Security Certification Report

Audit History
Audit model: codex Historical report
Skill name
ckm-design
Version
v3
Maintainer
nextlevelbuilder
Coverage
35 Files scanned · 5,279 Lines analyzed
Policy version
Unavailable

Highest confirmed finding severity

High

15 confirmed security findings require attention.

Installation context

Historical evidence

This report may not describe the currently installable artifact. Open the current Skill page for install guidance.

Open current Skill page

This report does not block or authorize the manifest or ZIP.

Most static findings are false positives from markdown code fences, design vocabulary, placeholder setup text, and normal output-file generation. Confirmed risks are concentrated in broad .env loading, Gemini API-key handling, external Gemini data transfer, remote template assets, unescaped generated HTML, and a documented no-sandbox Chrome export workflow.

Report position

Historical report

Open audit history before using this report to install.

Audit attestation

Not attestable

The required immutable binding is incomplete.

Human verification

Not verified

No human verification is recorded for this report.

Coverage

35 Files scanned · 5,279 Lines analyzed

33 items shown for review

Limitations

This report does not claim runtime or sandbox execution and does not prove the absence of side effects.

Evidence chain

Follow the evidence from source binding to the install contract. Available evidence supports verification; it is not a safety guarantee.

  1. Source

    Binding unavailable

  2. Artifact

    Identity incomplete

  3. Audit

    Complete

  4. Install contract

    Open manifest to verify

    Open manifest

Capabilities observed

Observed means this report recorded supporting evidence. Not recorded does not prove that a capability is absent.

Contains scripts

May execute code included with the Skill.

Not recorded by this audit

Network access

May connect to external services.

Observed in 4 evidence locations

Filesystem access

May read or write local files.

Observed in 57 evidence locations

Env variables

May read values from the process environment.

Observed in 27 evidence locations

External commands

May invoke commands or programs outside the Skill.

Observed in 91 evidence locations

Capability review items (18)
High
Generic API/secret keys
api_key = os.environ.get("GEMINI_API_KEY") or os.environ.get("GOOGLE_API_KEY")
The generator retrieves a Gemini or Google API key from the environment and passes it to the google-genai client. This is legitimate for the feature, but it is real credential use by community code.
High
Generic API/secret keys
client = genai.Client(api_key=api_key)
The generator retrieves a Gemini or Google API key from the environment and passes it to the google-genai client. This is legitimate for the feature, but it is real credential use by community code.
High
Generic API/secret keys
GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
The generator retrieves a Gemini or Google API key from the environment and passes it to the google-genai client. This is legitimate for the feature, but it is real credential use by community code.
High
Generic API/secret keys
client = genai.Client(api_key=GEMINI_API_KEY)
The generator retrieves a Gemini or Google API key from the environment and passes it to the google-genai client. This is legitimate for the feature, but it is real credential use by community code.
High
Generic API/secret keys
client = genai.Client(api_key=GEMINI_API_KEY)
The generator retrieves a Gemini or Google API key from the environment and passes it to the google-genai client. This is legitimate for the feature, but it is real credential use by community code.
High
Generic API/secret keys
GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
The generator retrieves a Gemini or Google API key from the environment and passes it to the google-genai client. This is legitimate for the feature, but it is real credential use by community code.
High
Generic API/secret keys
client = genai.Client(api_key=GEMINI_API_KEY)
The generator retrieves a Gemini or Google API key from the environment and passes it to the google-genai client. This is legitimate for the feature, but it is real credential use by community code.
Medium
Python environment access
if key not in os.environ:
The script reads or mutates os.environ as part of loading and using API credentials. This is expected for Gemini generation, but environment access can expose sensitive configuration to community code.
Medium
Python environment access
os.environ[key] = value.strip('"\'')
The script reads or mutates os.environ as part of loading and using API credentials. This is expected for Gemini generation, but environment access can expose sensitive configuration to community code.
Medium
Python environment access
api_key = os.environ.get("GEMINI_API_KEY") or os.environ.get("GOOGLE_API_KEY")
The script reads or mutates os.environ as part of loading and using API credentials. This is expected for Gemini generation, but environment access can expose sensitive configuration to community code.
Medium
Python environment access
if key not in os.environ:
The script reads or mutates os.environ as part of loading and using API credentials. This is expected for Gemini generation, but environment access can expose sensitive configuration to community code.
Medium
Python environment access
os.environ[key] = value.strip('"\'')
The script reads or mutates os.environ as part of loading and using API credentials. This is expected for Gemini generation, but environment access can expose sensitive configuration to community code.
Medium
Python environment access
GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
The script reads or mutates os.environ as part of loading and using API credentials. This is expected for Gemini generation, but environment access can expose sensitive configuration to community code.
Medium
Python environment access
if key not in os.environ:
The script reads or mutates os.environ as part of loading and using API credentials. This is expected for Gemini generation, but environment access can expose sensitive configuration to community code.
Medium
Python environment access
os.environ[key] = value.strip('"\'')
The script reads or mutates os.environ as part of loading and using API credentials. This is expected for Gemini generation, but environment access can expose sensitive configuration to community code.
Medium
Python environment access
GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
The script reads or mutates os.environ as part of loading and using API credentials. This is expected for Gemini generation, but environment access can expose sensitive configuration to community code.
Low
Hardcoded URL
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
The slide HTML template loads Chart.js from a public CDN, which creates a remote script dependency when used. This is expected functionality but is a real network and supply-chain consideration.
Low
Hardcoded URL
<link href="https://fonts.googleapis.com/css2?family={FONT}&display=swap" rel="stylesheet">
The social photo template loads Google Fonts from a remote URL, which creates an external network request. This is expected styling behavior but should be disclosed.

Risk findings

Confirmed security concerns are separated from items that still need review.

Confirmed security concerns (15)

RISK-001 High
Environment file access
"""Load environment variables from .env files"""
The generator loads .env files from the skill tree and hidden ~/.claude paths, then imports key-value pairs into the process environment. This is intended API-key loading, but community code reading hidden environment files is a real secret-handling risk.
RISK-002 High
Environment file access
Path(__file__).parent.parent.parent / ".env",
The generator loads .env files from the skill tree and hidden ~/.claude paths, then imports key-value pairs into the process environment. This is intended API-key loading, but community code reading hidden environment files is a real secret-handling risk.
RISK-003 High
Environment file access
Path.home() / ".claude" / "skills" / ".env",
The generator loads .env files from the skill tree and hidden ~/.claude paths, then imports key-value pairs into the process environment. This is intended API-key loading, but community code reading hidden environment files is a real secret-handling risk.
RISK-004 High
Environment file access
Path.home() / ".claude" / ".env"
The generator loads .env files from the skill tree and hidden ~/.claude paths, then imports key-value pairs into the process environment. This is intended API-key loading, but community code reading hidden environment files is a real secret-handling risk.
RISK-005 High
Environment file access
"""Load .env files in priority order"""
The generator loads .env files from the skill tree and hidden ~/.claude paths, then imports key-value pairs into the process environment. This is intended API-key loading, but community code reading hidden environment files is a real secret-handling risk.
RISK-006 High
Environment file access
Path(__file__).parent.parent.parent / ".env",
The generator loads .env files from the skill tree and hidden ~/.claude paths, then imports key-value pairs into the process environment. This is intended API-key loading, but community code reading hidden environment files is a real secret-handling risk.
RISK-007 High
Environment file access
Path.home() / ".claude" / "skills" / ".env",
The generator loads .env files from the skill tree and hidden ~/.claude paths, then imports key-value pairs into the process environment. This is intended API-key loading, but community code reading hidden environment files is a real secret-handling risk.
RISK-008 High
Environment file access
Path.home() / ".claude" / ".env"
The generator loads .env files from the skill tree and hidden ~/.claude paths, then imports key-value pairs into the process environment. This is intended API-key loading, but community code reading hidden environment files is a real secret-handling risk.
RISK-009 High
Environment file access
"""Load .env files in priority order"""
The generator loads .env files from the skill tree and hidden ~/.claude paths, then imports key-value pairs into the process environment. This is intended API-key loading, but community code reading hidden environment files is a real secret-handling risk.
RISK-010 High
Environment file access
Path(__file__).parent.parent.parent / ".env",
The generator loads .env files from the skill tree and hidden ~/.claude paths, then imports key-value pairs into the process environment. This is intended API-key loading, but community code reading hidden environment files is a real secret-handling risk.
RISK-011 High
Environment file access
Path.home() / ".claude" / "skills" / ".env",
The generator loads .env files from the skill tree and hidden ~/.claude paths, then imports key-value pairs into the process environment. This is intended API-key loading, but community code reading hidden environment files is a real secret-handling risk.
RISK-012 High
Environment file access
Path.home() / ".claude" / ".env"
The generator loads .env files from the skill tree and hidden ~/.claude paths, then imports key-value pairs into the process environment. This is intended API-key loading, but community code reading hidden environment files is a real secret-handling risk.
RISK-013 Medium
External Gemini Data Transfer
The logo, CIP, and icon generators send user prompts to Google Gemini, and the CIP generator can also send a user-provided logo image. This is expected for generation, but it is an external data transfer that should be explicit to users.
The scripts directly call client.models.generate_content with prompt text, and CIP includes logo_image in contents when provided.
RISK-014 Medium
Generated HTML Uses Unescaped User-Controlled Text
The CIP HTML renderer inserts brand names, industry/style labels, and file-derived deliverable labels into HTML using f-strings. A malicious value could inject HTML or script into the local presentation output.
The renderer interpolates CLI-derived and filename-derived strings into HTML without visible escaping or sanitization in the reviewed file.
RISK-015 Medium
Headless Browser Sandbox Disabled in Screenshot Workflow
The social photo export reference recommends running Chrome with --no-sandbox while opening local HTML. This reduces browser isolation if generated HTML or remote assets are malicious.
The documented command includes --no-sandbox and opens a file URL for screenshot capture, which is a known hardening concern.

Remediation

Suggested fixes recorded by this audit. Applying them is the maintainer’s responsibility.

  1. FIX-001
    High
    Broad .env loading from hidden paths
    Load only explicit GEMINI_API_KEY or GOOGLE_API_KEY values, and require user opt-in before reading hidden ~/.claude .env files.
  2. FIX-002
    Medium
    External Gemini data transfer
    Add clear prompts or documentation before sending user prompts, logo images, or generated asset context to Google Gemini.
  3. FIX-003
    Medium
    Unescaped values in generated HTML
    Escape brand names, industry labels, style labels, image alt text, and file-derived titles before writing HTML output.
  4. FIX-004
    Medium
    Headless Chrome runs with --no-sandbox in documentation
    Remove --no-sandbox from the recommended command unless a sandboxed environment requires it, and document the tradeoff.
  5. FIX-005
    Low
    Remote CDN and font dependencies in templates
    Prefer pinned local assets or document that generated slides and social images may load remote scripts or fonts.

Expert evidence

Immutable subject identity, scanner metadata, dismissed matches, and source-level evidence.

Artifact subject

Marketplace commit
Unavailable
Content hash
Unavailable
Tree hash
Unavailable
Skill path
Unavailable
Audit payload hash
Unavailable

Analysis metadata

Audit model: codex

Analysis state: Complete

Scope is limited to the recorded files, lines, methods, and evidence. No runtime or sandbox execution is claimed.

Static false positives ignored (1)
High
LLM role tokens injection
output.append(f"\n🎯 COLOR SYSTEM:")
Force-confirmed blocker/high static finding; AI dismissal overridden.

Verify and export

The manifest and lockfile bind install artifacts to cryptographic hashes. This integrity claim is separate from the security assessment.

Audit attestation: not_attestable