Back to skill

Security audit

PopAI Presentation Slides

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it needs review because it encourages storing an API token in plaintext and logs sensitive prompt and file details.

Review before installing. Use a scoped PopAI token, do not store it in TOOLS.md or any repository file, and avoid sending confidential, regulated, or internal documents unless PopAI is approved for that data. Expect prompts, URLs, selected local files, template files, filenames, and channel information to be sent to PopAI and potentially appear in local execution logs.

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

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:19
Finding

Unsafe Recommendation to Persist an Access Token in a Plaintext Documentation File

Content
View full analysis
` Tips: You can save the key in `TOOLS.md` for future reference. ``` ### Technical Analysis The Skill recommends saving the PopAI access token in `TOOLS.md`. This is a plaintext documentation file rather than a protected credential store. It may be committed to source control, copied into support bundles, indexed by development tools, included in backups, or made readable to other users and agents with access to the project. Although the script itself correctly reads the credential from the `POPAI_ACCESS_TOKEN` environment variable, the additional persistence recommendation undermines that safer mechanism. A long-lived API token should not be stored in repository documentation. ### Attack Path 1. A user follows the Skill instructions and writes the PopAI access token into `TOOLS.md`. 2. The file is committed to a repository, synchronized to cloud storage, included in an archive, exposed through logs or support tooling, or read by another local user or agent. 3. An unauthorized party extracts the token. 4. The party submits authenticated requests to the PopAI API under the victim's account. 5. The exposed token remains usable until it expires or is explicitly revoked. No direct automated credential theft is present in the audited code; exploitation depends on the user following the unsafe storage recommendation and the resulting file becoming accessible. ### Impact Assessment An exposed token could permit unauthorized use of the PopAI account within the permissions granted to that token. Potential effects include unauthorized API consumption, quota or billing impact, generation of p ...[truncated 272 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
generate_ppt.py:105
Finding

User Prompts, File Metadata, Object URLs, and Channel Identifiers Are Logged to Standard Error

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Tainted flow: 'api_key' from os.getenv (line 284, credential/environment) → requests.post (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 · generate_ppt.py (reported line 60)May include surrounding context.

python
content_type = mimetypes.guess_type(file_path)[0] or "application/octet-stream"

    # Get presigned post
    resp = requests.post(
        PRESIGN_URL,
        headers=_headers(api_key),
        json={"md5": md5, "bucket": S3_BUCKET, "prefix": key, "contentType": content_type},

Tainted flow: 'api_key' from os.getenv (line 284, credential/environment) → requests.post (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 · generate_ppt.py (reported line 106)May include surrounding context.

python
payload["isUploadToEnhance"] = True

    print(f"getChannel payload: {json.dumps(payload, ensure_ascii=False)}", file=sys.stderr)
    resp = requests.post(f"{BASE_URL}/getChannel", headers=_headers(api_key), json=payload)
    resp.raise_for_status()
    channel_id = (resp.json().get("data") or {}).get("channelId")
    if not channel_id:

Tainted flow: 'api_key' from os.getenv (line 284, credential/environment) → requests.post (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 · generate_ppt.py (reported line 241)May include surrounding context.

python
payload["pptTpl"] = tpl_info["url"]

    print(f"send payload: {json.dumps(payload, ensure_ascii=False)}", file=sys.stderr)
    resp = requests.post(
        f"{BASE_URL}/send", headers=_headers(api_key, accept="text/event-stream"),
        json=payload, stream=True,
    )

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill explicitly supports uploading local files and embedding URLs for automatic fetching by PopAI, but it does not clearly warn that this material is sent to a third-party API for processing. Users may unknowingly disclose sensitive documents, internal URLs, or proprietary data to an external service.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The instructions tell the agent to ask the user for an access token and suggest saving it in TOOLS.md for future reference, which encourages persistent storage of a credential in a likely insecure location. This creates credential exposure risk through logs, workspace files, later prompts, or unrelated tools that can read local files.

Content

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

md
## Setup

1. Ask user to sign up and obtain their Access Token at: https://www.popai.pro/popai-skill
2. Once user provides the token, set it in environment: `export POPAI_ACCESS_TOKEN=<token>`

Tips: You can save the key in `TOOLS.md` for future reference.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill performs network access and consumes an environment secret, but it does not declare explicit tool scope or permissions boundaries. That increases the chance an agent invokes it without clear user awareness or sandbox policy review, especially since it can upload files and contact a third-party API.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The trigger text is broad enough to match many ordinary requests about slides or presentations, which can cause over-invocation of a third-party-integrated skill. In this context, accidental routing is more dangerous because the skill may send user content, URLs, and files to an external service and use stored credentials.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · generate_ppt.py (reported line 17)May include surrounding context.

python
from concurrent.futures import ThreadPoolExecutor
import requests

BASE_URL = "https://api.popai.pro/api/v1/chat"
PRESIGN_URL = "https://api.popai.pro/py/api/v1/chat/getPresignedPost"
S3_UPLOAD_URL = "https://popai-file.s3-accelerate.amazonaws.com/"
S3_BUCKET = "popai-file"

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · generate_ppt.py (reported line 18)May include surrounding context.

python
from concurrent.futures import ThreadPoolExecutor
import requests

BASE_URL = "https://api.popai.pro/api/v1/chat"
PRESIGN_URL = "https://api.popai.pro/py/api/v1/chat/getPresignedPost"
S3_UPLOAD_URL = "https://popai-file.s3-accelerate.amazonaws.com/"
S3_BUCKET = "popai-file"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill uploads local files to external infrastructure (PopAI/S3) but provides no explicit user-facing warning or confirmation at the point of transmission. In an agent setting, users may provide sensitive local documents assuming local processing, so silent upload can cause unintended disclosure of confidential data.

Content

No source excerpt is available for this finding.

Tainted flow: 'fields' from requests.post (line 66, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · generate_ppt.py (reported line 72)May include surrounding context.

python
# Upload to S3
    with open(file_path, "rb") as f:
        upload_resp = requests.post(
            S3_UPLOAD_URL,
            files={"file": (filename, f, content_type)},
            data={

Tainted flow: 'payload' from requests.post (line 232, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · generate_ppt.py (reported line 106)May include surrounding context.

python
payload["isUploadToEnhance"] = True

    print(f"getChannel payload: {json.dumps(payload, ensure_ascii=False)}", file=sys.stderr)
    resp = requests.post(f"{BASE_URL}/getChannel", headers=_headers(api_key), json=payload)
    resp.raise_for_status()
    channel_id = (resp.json().get("data") or {}).get("channelId")
    if not channel_id:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script sends the user's prompt, file URLs, and optional template URL to a third-party API without an explicit privacy notice. Because the skill advertises built-in research and document support, prompts may contain proprietary or personal information whose remote transmission should be made explicit.

Content

No source excerpt is available for this finding.

Tainted flow: 'payload' from requests.post (line 232, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · generate_ppt.py (reported line 241)May include surrounding context.

python
payload["pptTpl"] = tpl_info["url"]

    print(f"send payload: {json.dumps(payload, ensure_ascii=False)}", file=sys.stderr)
    resp = requests.post(
        f"{BASE_URL}/send", headers=_headers(api_key, accept="text/event-stream"),
        json=payload, stream=True,
    )

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The code accesses a sensitive credential from the POPAI_ACCESS_TOKEN environment variable, but it does not disclose to the user that a bearer token will be used for authenticating requests to the external API. Under the rule, access to sensitive environment variables should have some visible explanation or warning.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.