Back to skill

Security audit

Codex PPT

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent PPT generation helper, but its optional API fallback and persistent shared runtime create credential and data-handling risks that need review before installation.

Install only if you are comfortable with a shared local runtime that can store API credentials and send presentation text and selected images to an image provider. Prefer the built-in image tool, avoid configuring untrusted OPENAI_BASE_URL values, do not put real API keys directly in command lines, and review any files under ~/.codex-ppt-skill/references before letting the skill reuse saved styles.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/codex_ppt_runtime.py:151
Finding

Arbitrary API base URL can receive credentials and private presentation content

Content
View full analysis
bool: endpoint = base_url.rstrip("/") + "/models" req = urllib.request.Request( endpoint, headers={"Authorization": f"Bearer {api_key}"}, method="GET", ) try: with urllib.request.urlopen(req, timeout=timeout) as resp: ``` ```python # scripts/image_providers/openai_compatible.py:155-162 def _create_client(self) -> Any: if self._client_factory is not None: return self._client_factory() try: from openai import OpenAI except ImportError as exc: raise RuntimeError( f"openai SDK not installed in the active environment. {_dependency_hint('openai')}" ) from exc return OpenAI(api_key=self.api_key, base_url=self.base_url) ``` ```python # scripts/image_providers/openai_compatible.py:167-183 def _create_async_client(self) -> Any: if self._async_client is not None: return self._async_client if self._async_client_factory is not None: self._async_client = self._async_client_factory() return self._async_client try: from openai import AsyncOpenAI except ImportError as exc: try: import openai as _openai # noqa: F401 except ImportError: rais ...[truncated 3771 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/image_providers/factory.py:17
Finding

AtlasCloud provider detection accepts attacker-controlled lookalike domains

Content
View full analysis
bool: if not base_url: return False hostname = urlparse(base_url).hostname or "" return "atlascloud.ai" in hostname.lower() ``` ```python # scripts/image_gen.py:105-107 def _is_atlascloud_base_url(base_url: str) -> bool: hostname = urlparse(base_url).hostname or "" return "atlascloud.ai" in hostname.lower() ``` ```python # scripts/codex_ppt_runtime.py:212-214 def _is_atlascloud_base_url(base_url: str) -> bool: hostname = urllib.parse.urlparse(base_url).hostname or "" return "atlascloud.ai" in hostname.lower() ``` ### Technical Analysis The implementation identifies AtlasCloud by checking whether the hostname contains the string `atlascloud.ai`. Substring matching does not establish domain ownership or a DNS-label boundary. For example, all of the following satisfy the check despite not necessarily being controlled by AtlasCloud: ```text atlascloud.ai.attacker.example evilatlascloud.ai notatlascloud.ai.example ``` Once classified as AtlasCloud, the Skill selects `AtlasCloudImageProvider`. That adapter sends the configured Bearer credential and request content to the origin derived from the supplied URL. Consequently, the flawed classification can make an attacker-controlled host appear to be a recognized provider. The same defective check is duplicated in three locations, increasing the chance that provider selection, diagnostics, and user-facing labels behave inconsistently after a partial fix. ### Attack Path 1. An attacker supplies a base URL whose hostname contains `atlascloud.ai` as a substring, such as `https://atlascloud.ai.attacker.example`. 2 ...[truncated 852 chars]
Remediation
View remediation
bool: if not base_url: return False parsed = urlparse(base_url) return parsed.scheme == "https" and (parsed.hostname or "").lower() == "api.atlascloud.ai" ``` 2. If multiple official subdomains are required, use an explicit allowlist. Do not use unrestricted substring matching. 3. Centralize provider identification in one module and reuse it from diagnostics and image generation. 4. Reject non-HTTPS AtlasCloud URLs and unexpected ports. 5. Add negative tests for `atlascloud.ai.attacker.example`, `evilatlascloud.ai`, user-information URL tricks, mixed case, trailing dots, and internationalized-domain edge cases. 6. Require explicit confirmation before sending credentials to any host not in the built-in provider allowlist. ]]>

T02 · Agent Memory Poisoning

Warning
Location
docs/outline-style-and-sample.md:73
Finding

Persistent custom Markdown references can poison future agent sessions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/codex_ppt_runtime.py:262
Finding

API keys are accepted through process command-line arguments

Content
View full analysis
int: home = _runtime_home() _ensure_dirs(home) env_file = _env_path(home) values = _parse_env_file(env_file) if args.api_key: values["OPENAI_API_KEY"] = args.api_key if args.base_url is not None: values["OPENAI_BASE_URL"] = args.base_url.strip() if args.model is not None: values["CODEX_PPT_IMAGE_MODEL"] = args.model.strip() if args.clear_base_url: values.pop("OPENAI_BASE_URL", None) _write_env_file(env_file, values) print(f"Wrote {env_file}") for key in ENV_FIELDS: value = values.get(key, "") if key == "OPENAI_API_KEY": value = _mask_secret(value) print(f"{key}={value or ''}") ``` ```python # scripts/codex_ppt_runtime.py:262-266 config = subparsers.add_parser("config", help="Write or update shared .env") config.add_argument("--api-key") config.add_argument("--base-url") config.add_argument("--clear-base-url", action="store_true") config.add_argument("--model") ``` ### Technical Analysis The resultin ...[truncated 1444 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Bootstrap installs mutable third-party dependency versions without integrity pinning

Content
View full analysis
int: home = _runtime_home() _ensure_dirs(home) python = _venv_python(home) if not python.exists(): print(f"Creating virtual environment: {home / '.venv'}") venv.EnvBuilder(with_pip=True, clear=False).create(home / ".venv") else: print(f"Virtual environment already exists: {home / '.venv'}") requirements = _requirements_path() if not requirements.exists(): _die(f"requirements.txt not found: {requirements}") cmd = [str(python), "-m", "pip", "install", "-r", str(requirements)] if args.upgrade: cmd.insert(4, "-U") print(f"Installing dependencies from: {requirements}") subprocess.run(cmd, check=True) ``` ```text # requirements.txt:1-4 python-pptx>=1.0.2 Pillow>=10.0.0 openai>=2.0.0 filelock>=3.16.0 ``` ### Technical Analysis The bootstrap command installs packages from the configured Python package index using lower-bound constraints only. Any future package release satisfying those constraints may be installed. The reviewed Skill therefore does not fully determine the code that will execute after bootstrap. Python package installation may execute package-controlled build or installation logic. Even for well-known dependencies, mutable ranges create exposure to compromised future releases, malicious index substitution, dependency-resolution changes, and unexpected breaking behavior. The `--upgrade` option expands this exposure by deliberately selecting newer releases. This finding does not establish that the named packages are malicious. The issue is the absence of exact version and artifact-integrity controls. ### Attack Path 1. A malicious or compromised ...[truncated 1021 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (68)

Tp4

High
Category
MCP Tool Poisoning
Confidence
88% confidence
Finding

The skill also functions as a direct image-generation/editing and batch job client using external APIs and local env loading, which goes beyond the stated PPT/PPTX purpose. That hidden breadth increases the risk of unexpected data transfer, misuse of credentials, and agent actions the user did not knowingly authorize.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill also functions as a direct image-generation/editing and batch job client using external APIs and local env loading, which goes beyond the stated PPT/PPTX purpose. That hidden breadth increases the risk of unexpected data transfer, misuse of credentials, and agent actions the user did not knowingly authorize.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The skill also functions as a direct image-generation/editing and batch job client using external APIs and local env loading, which goes beyond the stated PPT/PPTX purpose. That hidden breadth increases the risk of unexpected data transfer, misuse of credentials, and agent actions the user did not knowingly authorize.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill also functions as a direct image-generation/editing and batch job client using external APIs and local env loading, which goes beyond the stated PPT/PPTX purpose. That hidden breadth increases the risk of unexpected data transfer, misuse of credentials, and agent actions the user did not knowingly authorize.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill also functions as a direct image-generation/editing and batch job client using external APIs and local env loading, which goes beyond the stated PPT/PPTX purpose. That hidden breadth increases the risk of unexpected data transfer, misuse of credentials, and agent actions the user did not knowingly authorize.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill also functions as a direct image-generation/editing and batch job client using external APIs and local env loading, which goes beyond the stated PPT/PPTX purpose. That hidden breadth increases the risk of unexpected data transfer, misuse of credentials, and agent actions the user did not knowingly authorize.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill also functions as a direct image-generation/editing and batch job client using external APIs and local env loading, which goes beyond the stated PPT/PPTX purpose. That hidden breadth increases the risk of unexpected data transfer, misuse of credentials, and agent actions the user did not knowingly authorize.

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 72)May include surrounding context.

md
- Before writing or updating `outline.md`, read `docs/workflow-gates-and-progress.md` and `docs/outline-style-and-sample.md`.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Before writing or updating `outline.md`, read `docs/workflow-gates-and-progress.md` and `docs/outline-style-and-sample.md`.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Before writing or updating `outline.md`, read `docs/workflow-gates-and-progress.md` and `docs/outline-style-and-sample.md`.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Before writing or updating `outline.md`, read `docs/workflow-gates-and-progress.md` and `docs/outline-style-and-sample.md`.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- If asked to save the current deck style or a supplied image/PDF/PPT/PPTX style, read `docs/style-library.md`.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · docs/backend-selection.md (reported line 34)May include surrounding context.

CLI/API fallback:

text
我检查后没有可用的内置图片生成工具,或内置工具缺少本页必需能力,因此准备使用本地 API/CLI fallback 生成样张,读取 ~/.codex-ppt-skill/.env 中的 OPENAI_BASE_URL / CODEX_PPT_IMAGE_MODEL 配置。可以开始生成 1 页样张吗?

Wait for confirmation before generating the sample slide. If the user questions the backend, resolve that before continuing.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · docs/image-model-configuration.md (reported line 79)May include surrounding context.

CLI/API fallback:

text
我检查后没有可用的内置图片生成工具,或内置工具缺少本页必需能力,因此准备使用本地 API/CLI fallback 生成样张,读取 ~/.codex-ppt-skill/.env 中的 OPENAI_BASE_URL / CODEX_PPT_IMAGE_MODEL 配置。可以开始生成 1 页样张吗?

Wait for confirmation before generating the sample slide. If the user questions the backend, resolve that before continuing.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/codex_ppt_runtime.py (reported line 45)May include surrounding context.

python
def _env_path(home: Path) -> Path:
    return home / ".env"


def _requirements_path() -> Path:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/codex_ppt_runtime.py (reported line 262)May include surrounding context.

python
def _env_path(home: Path) -> Path:
    return home / ".env"


def _requirements_path() -> Path:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/image_gen.py (reported line 69)May include surrounding context.

python
def _env_path(home: Path) -> Path:
    return home / ".env"


def _requirements_path() -> Path:

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/image_gen.py (reported line 191)May include surrounding context.

python
_die(f"Prompt file not found: {path}")
        return path.read_text(encoding="utf-8").strip()
    if prompt:
        return prompt.strip()
    _die("Missing prompt. Use --prompt or --prompt-file.")
    return ""  # unreachable

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/image_gen.py (reported line 380)May include surrounding context.

python
_die(f"Prompt file not found: {path}")
        return path.read_text(encoding="utf-8").strip()
    if prompt:
        return prompt.strip()
    _die("Missing prompt. Use --prompt or --prompt-file.")
    return ""  # unreachable

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill declares access to environment variables, file I/O, network, and shell-like capabilities through its documented workflow, but it does not publish an explicit tool/permission scope. That increases the chance an agent runtime grants broader access than users expect, especially because the skill can read API credentials, write project files, invoke scripts, and call external services.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
81% confidence
Finding

The skill explicitly persists substantial workflow artifacts across phases, including deck specs, prompt jobs, slide images, notes, and run-state files. Persisting these materials can retain sensitive source content, generated prompts, asset mappings, and approval history on disk, creating privacy and data-retention risk if the workspace is shared or insufficiently protected.

Content

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

md
## Hard Constraints

- Read the relevant `Reference Map` files before each phase. This file is the orchestration contract; detailed rules live in `docs/` and worker prompts in `prompts/`.
- Respect approval gates. Do not create final `deck_spec.json`, `speech.md`, prompt jobs, slide images, or `.pptx` before the approvals in `docs/workflow-gates-and-progress.md`.
- After the user approves the sample slide and authorizes full-deck generation, every remaining slide image job must be dispatched to a slide subagent whenever subagents are available.
- The main agent owns orchestration, prompt jobs, state recording, QA, speaker notes, and assembly. Do not silently replace available slide subagents with sequential production.
- Every final `origin_image/slide_XX.png` must be generated by the selected image backend: built-in image generation/editing tool or `scripts/image_gen.py`.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The sample confirmation text for both backend paths is written only in Chinese, which instructs or strongly implies the skill should respond in a specific language regardless of the user's preference. This is a natural-language locale policy issue because the file does not offer a language choice or document a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · docs/cli-api-fallback.md (reported line 9)May include surrounding context.

Runtime Setup

CLI/API fallback commands use the shared runtime environment. Before running scripts/assemble_ppt.py or fallback image commands, make sure the shared runtime exists. If ~/.codex-ppt-skill/.venv/bin/python is missing, or if importing script dependencies fails, create or refresh the environment:

bash
python3 {skill_root}/scripts/codex_ppt_runtime.py bootstrap

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · docs/cli-api-fallback.md (reported line 15)May include surrounding context.

python3 {skill_root}/scripts/codex_ppt_runtime.py bootstrap

text

This is an internal setup step for the skill. Do not ask the user to run it unless dependency installation fails and user approval or troubleshooting is required.

The fallback CLI loads `~/.codex-ppt-skill/.env` automatically for `OPENAI_API_KEY`, `OPENAI_BASE_URL`, and `CODEX_PPT_IMAGE_MODEL`. Do not manually parse `.env`. For API key, base URL, model, and config troubleshooting, read `image-model-configuration.md` only after the fallback CLI reports missing or invalid configuration, when the user explicitly wants to change those settings, or when a real API call reports authentication, permission, base URL, or model availability failure.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · docs/project-assembly-and-reporting.md (reported line 107)May include surrounding context.

python3 {skill_root}/scripts/codex_ppt_runtime.py bootstrap

text

This is an internal setup step for the skill. Do not ask the user to run it unless dependency installation fails and user approval or troubleshooting is required.

The fallback CLI loads `~/.codex-ppt-skill/.env` automatically for `OPENAI_API_KEY`, `OPENAI_BASE_URL`, and `CODEX_PPT_IMAGE_MODEL`. Do not manually parse `.env`. For API key, base URL, model, and config troubleshooting, read `image-model-configuration.md` only after the fallback CLI reports missing or invalid configuration, when the user explicitly wants to change those settings, or when a real API call reports authentication, permission, base URL, or model availability failure.

Static analysis

No suspicious patterns detected.