Back to skill

Security audit

sn-ppt-doctor

Security checks for vulnerabilities and agentic risk

Overview

This diagnostic skill is not deceptive, but it should be reviewed because it handles and stores API keys in local .env files and can run checks based on environment-controlled paths.

Review before installing. This tool is purpose-built for configuring the PPT skill family, but only run it in a trusted workspace, avoid relying on workspace-provided .env files from untrusted projects, and prefer setting API keys through a safer secret manager or environment configuration instead of entering them interactively into a plaintext .env file.

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

Warning
Location
ppt_doctor/check_environment.py:464
Finding

API Key Written to a Potentially Insecure or Symbolically Linked File

Content
View full analysis
FillResult: missing: list[tuple[str, str]] = [ (name, desc) for name, desc in REQUIRED if not os.environ.get(name, "").strip() ] if not missing: return FillResult(written=False, path=None) if non_interactive: return FillResult(written=False, path=None) lines: list[str] = [] for name, desc in missing: value = input(f"{name} ({desc}): ").strip() if value: lines.append(f"{name}={value}") if not lines: return FillResult(written=False, path=None) env_path.parent.mkdir(parents=True, exist_ok=True) existing = env_path.read_text() if env_path.exists() else "" with env_path.open("w", encoding="utf-8") as f: if existing: f.write(existing) if not existing.endswith("\n"): f.write("\n") f.write("\n".join(lines) + "\n") return FillResult(written=True, path=env_path) ``` The package implementation duplicates the same behavior: ```python def interactive_fill_env(env_path: Path, non_interactive: bool = False) -> FillResult: missing: list[tuple[str, str]] = [ (name, desc) for name, desc in REQUIRED if not os.environ.get(name, "").strip() ] if not missing: return FillResult(written=False, path=None) if non_interactive: return FillResult(written=False, path=None) lines: list[str] = [] for name, desc in missing: value = input(f"{name} ({desc}): ").strip() if value: lines.append(f"{name}={value}") if not lines: return Fil ...[truncated 3171 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (29)

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

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 · ppt_doctor/__main__.py (reported line 15)May include surrounding context.

python
def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(prog="sn-ppt-doctor")
    parser.add_argument("--non-interactive", action="store_true", help="Skip interactive .env prompts")
    parser.add_argument("--env-path", type=Path, default=Path.cwd() / ".env")
    args = parser.parse_args(argv)

    print("== sn-ppt-doctor: environment check ==\n")

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 · ppt_doctor/check_environment.py (reported line 57)May include surrounding context.

python
def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(prog="sn-ppt-doctor")
    parser.add_argument("--non-interactive", action="store_true", help="Skip interactive .env prompts")
    parser.add_argument("--env-path", type=Path, default=Path.cwd() / ".env")
    args = parser.parse_args(argv)

    print("== sn-ppt-doctor: environment check ==\n")

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 · ppt_doctor/check_environment.py (reported line 503)May include surrounding context.

python
def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(prog="sn-ppt-doctor")
    parser.add_argument("--non-interactive", action="store_true", help="Skip interactive .env prompts")
    parser.add_argument("--env-path", type=Path, default=Path.cwd() / ".env")
    args = parser.parse_args(argv)

    print("== sn-ppt-doctor: environment check ==\n")

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

Including Path.cwd()/.env in the automatic search path causes the skill to import secrets and configuration from the current working directory, which in agent environments may be workspace content influenced by an untrusted user or task. That can lead to environment poisoning: attacker-supplied API keys, base URLs, or path variables could alter subsequent behavior, redirect requests, or cause the tool to execute against unintended resources.

Content

Scanner excerpt · ppt_doctor/checks.py (reported line 22)May include surrounding context.

python
from dotenv import load_dotenv
    _script = Path(__file__).resolve()
    _repo_root = _script.parents[3]
    for _candidate in (_repo_root / ".env", _repo_root / "skills" / ".env", Path.cwd() / ".env"):
        if _candidate.exists():
            load_dotenv(_candidate, override=False)
except ImportError:

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · ppt_doctor/check_environment.py (reported line 184)May include surrounding context.

python
)
    # The runner's package root is the parent of sn_image_base/ (i.e. runner.parent.parent)
    skill_root = str(runner.parent.parent)
    env = os.environ.copy()
    existing_pp = env.get("PYTHONPATH", "")
    env["PYTHONPATH"] = os.pathsep.join([skill_root, existing_pp]) if existing_pp else skill_root
    try:

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · ppt_doctor/checks.py (reported line 148)May include surrounding context.

python
)
    # The runner's package root is the parent of sn_image_base/ (i.e. runner.parent.parent)
    skill_root = str(runner.parent.parent)
    env = os.environ.copy()
    existing_pp = env.get("PYTHONPATH", "")
    env["PYTHONPATH"] = os.pathsep.join([skill_root, existing_pp]) if existing_pp else skill_root
    try:

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 · SKILL.md (reported line 5)May include surrounding context.

md
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

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 · SKILL.md (reported line 47)May include surrounding context.

md
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

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 · ppt_doctor/__main__.py (reported line 14)May include surrounding context.

python
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

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 · ppt_doctor/__main__.py (reported line 30)May include surrounding context.

python
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

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 · ppt_doctor/check_environment.py (reported line 20)May include surrounding context.

python
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

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 · ppt_doctor/check_environment.py (reported line 41)May include surrounding context.

python
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

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 · ppt_doctor/check_environment.py (reported line 44)May include surrounding context.

python
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

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 · ppt_doctor/check_environment.py (reported line 45)May include surrounding context.

python
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

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 · ppt_doctor/check_environment.py (reported line 46)May include surrounding context.

python
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

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 · ppt_doctor/check_environment.py (reported line 451)May include surrounding context.

python
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

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 · ppt_doctor/check_environment.py (reported line 502)May include surrounding context.

python
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

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 · ppt_doctor/check_environment.py (reported line 513)May include surrounding context.

python
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

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 · ppt_doctor/check_environment.py (reported line 525)May include surrounding context.

python
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

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 · ppt_doctor/checks.py (reported line 17)May include surrounding context.

python
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

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 · ppt_doctor/interactive.py (reported line 1)May include surrounding context.

python
"""Interactive .env filler for sn-ppt-doctor.

Prompts only for missing required env vars; skips ones already set.
"""

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill explicitly describes capabilities to read environment variables, write a .env file, and invoke shell commands, but it does not declare any tool scope or permission boundaries. In a skill system, undeclared privileged capabilities reduce reviewability and can enable over-broad execution, especially because the skill handles secrets and filesystem writes.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · ppt_doctor/check_environment.py (reported line 405)May include surrounding context.

python
)

    try:
        result = subprocess.run(
            ["npx", "playwright", "install", "--dry-run", "chromium"],
            capture_output=True, text=True, timeout=30,
            cwd=str(base),

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script interactively collects an API key and persists it to a local .env file without warning the user that the secret will be stored on disk, potentially in a workspace that may be synced, shared, or accidentally committed. This increases the chance of credential exposure through local compromise, backups, logs, or source-control mistakes.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.