Back to skill

Security audit

free quota text to image

Security checks for vulnerabilities and agentic risk

Overview

The skill largely does what it advertises, but it handles API tokens and external provider URLs in ways users should review before installing.

Install only if you are comfortable sending prompts and API tokens to the configured providers. Use low-privilege provider tokens, avoid sensitive or proprietary prompt text, prefer HTTPS-only trusted endpoints, disable prompt optimization for sensitive prompts, and review or remove the token_status.json state file because it can contain full tokens in plaintext.

Vulnerability Patterns
  • 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
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/token_pool.py:72
Finding

Provider Tokens Persisted in Plaintext Without Restrictive File Permissions

Content
View full analysis
None: if not token: return self._reset_if_new_day(provider) provider_state = self._state.setdefault(provider, {}) exhausted = provider_state.setdefault("exhausted", {}) exhausted[token] = True self._save_state() ``` ```python def _save_state(self) -> None: self.state_file.parent.mkdir(parents=True, exist_ok=True) self.state_file.write_text( json.dumps(self._state, indent=2, ensure_ascii=True), encoding="utf-8", ) ``` ### Technical Analysis When a token encounters a quota error, the complete bearer token is inserted as a JSON object key and persisted to `token_status.json`. The implementation does not store a hash, fingerprint, or opaque token identifier. The state directory and file are created using the process's default permission behavior. No explicit owner-only mode such as `0700` for the directory or `0600` for the file is enforced. The resulting exposure depends on the process umask and surrounding filesystem permissions. The plaintext storage design is also documented in `references/token-rotation-policy.md`, whose example schema contains a complete token as a key. A token being quota-exhausted does not mean it is revoked; it may become usable again after a quota reset or retain access to other provider functionality. ### Attack Path 1. A user configures valid provider bearer tokens and invokes image generation. 2. A provider returns a response classified as a quota failure. 3. `mark_exhausted()` stores the complete token in the persistent state dictionary. 4. `_save_state()` writes the token to the configured state file in plaintext. 5. Another local user, compromised process, backup agent, or file ...[truncated 656 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run_text2img.py:422
Finding

Unvalidated Provider-Controlled Image URL Enables Server-Side Request Forgery

Content
View full analysis
None: output_path.parent.mkdir(parents=True, exist_ok=True) response = requests.get(url, stream=True, timeout=timeout) response.raise_for_status() with output_path.open("wb") as handle: for chunk in response.iter_content(chunk_size=8192): if chunk: handle.write(chunk) ``` The URL is accepted directly from provider responses, including these paths: ```python image_url = _nested_value(body, ["data", 0, "url"]) ``` ```python output_images = poll_body.get("output_images") if isinstance(output_images, list) and output_images: return GenerationResult( url=output_images[0], provider="modelscope", model=model, seed=seed, steps=steps, guidance_scale=guidance, raw_response=poll_body, ) ``` ### Technical Analysis When the user supplies `--output`, the Skill performs an HTTP request to the URL returned by an external image provider. The URL is not restricted by scheme, hostname, port, resolved address, or provider ownership. The default behavior of `requests.get()` also permits redirects. Consequently, even a URL initially hosted on an expected provider domain can redirect the request to a loopback, link-local, private-network, or cloud metadata address. No response-size limit or image content-type validation is enforced. A provider can therefore return an internal-resource URL or an unexpectedly large/non-image response, which the Skill writes to disk. ### Attack Path 1. The user runs the Skill with `--output`. 2. A compromised, malicious, or incorrectly configured provider returns an image URL targeting: - `127.0.0.1` or `::1`; - a private-network ser ...[truncated 950 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/provider_clients.py:334
Finding

OpenAI-Compatible Endpoint Can Transmit Bearer Tokens Over Plaintext HTTP

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/requirements.txt:1
Finding

Dependencies Are Installed From Broad Version Ranges Without Integrity Locking

Content
View full analysis
=2.31.0,<3 PyYAML>=6.0,<7 ``` The installation instructions execute these unconstrained selections: ```bash python -m pip install -r {baseDir}/scripts/requirements.txt ``` ### Technical Analysis The dependency file permits any future `requests` 2.x release from version 2.31.0 onward and any future PyYAML 6.x release. It does not include cryptographic hashes or a lock file. As a result, two installations performed at different times may install different code even when the Skill itself has not changed. If a future dependency release is compromised, removed and replaced, or contains a security regression, the unsafe version can be selected automatically. No evidence was found that either named dependency is currently malicious or typosquatted. The issue is the absence of reproducible and integrity-verified dependency resolution. ### Attack Path 1. An attacker compromises an allowed future release or its package publication channel. 2. A user follows the documented installation command after that release becomes available. 3. Pip resolves the broad version range to the compromised release. 4. The package executes within the Python environment during installation or when imported by the Skill. 5. The compromised dependency receives the same filesystem, environment, and network privileges as the Skill process. ### Impact Assessment A compromised dependency could access provider tokens in environment variables and configuration, inspect user prompts, read or modify files available to the process, and perform network requests. The likelihood is lower than the direct coding flaws because exploitation depends on a future supply-chain compromise or defective allowed release. ]]>
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (40)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The risk is materially higher for user-configurable OpenAI-compatible endpoints because the code will forward prompts and bearer tokens to arbitrary third-party infrastructure. In this skill context, which explicitly supports private endpoints and provider routing, that greatly increases the chance of covert data sharing, credential leakage, or misuse through hostile endpoint configuration.

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 · scripts/run_text2img.py (reported line 72)May include surrounding context.

python
def load_dotenv() -> None:
    script_dir = Path(__file__).resolve().parent
    candidates = [
        Path.cwd() / ".env",
        script_dir.parent / ".env",
        script_dir.parent.parent / ".env",
    ]

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/run_text2img.py (reported line 73)May include surrounding context.

python
def load_dotenv() -> None:
    script_dir = Path(__file__).resolve().parent
    candidates = [
        Path.cwd() / ".env",
        script_dir.parent / ".env",
        script_dir.parent.parent / ".env",
    ]

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/run_text2img.py (reported line 74)May include surrounding context.

python
def load_dotenv() -> None:
    script_dir = Path(__file__).resolve().parent
    candidates = [
        Path.cwd() / ".env",
        script_dir.parent / ".env",
        script_dir.parent.parent / ".env",
    ]

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises commands that can install dependencies, read configuration files, access environment-backed tokens, write output files, and call external network providers, but it declares no explicit tool scope or permission boundaries. That creates an over-privileged execution model where an agent may use broader file, network, and environment access than users expect, increasing the chance of unintended data exposure or unsafe side effects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly routes prompts across multiple third-party providers and may send the prompt to provider text models for optimization or translation, yet it gives no user-facing notice that prompt contents may leave the local environment. Users may include sensitive or proprietary text in prompts, and the multi-provider fallback design increases exposure by potentially transmitting the same content to several services.

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 · assets/config.example.yaml (reported line 47)May include surrounding context.

yaml
a4f: gemini-2.5-flash-lite
  system_prompt: |
    I am a master AI image prompt engineering advisor, specializing in crafting prompts that yield cinematic,
    hyper-realistic visual narratives for advanced generative models. Rewrite and expand user prompts into
    concise, high-quality image prompts with no markdown and no extra commentary.

translation:

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · assets/config.example.yaml (reported line 22)May include surrounding context.

yaml
"T2I_PEINTURE_GITEE_TOKENS": "gitee_xxx",
          "T2I_PEINTURE_MODELSCOPE_TOKENS": "ms_xxx",
          "T2I_PEINTURE_A4F_TOKENS": "",
          "T2I_PEINTURE_OPENAI_COMPATIBLE_URL": "https://api.siliconflow.cn/v1",
          "T2I_PEINTURE_OPENAI_COMPATIBLE_TOKENS": "sk_xxx,sk_yyy"
        }
      }

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · references/openclaw-integration.md (reported line 21)May include surrounding context.

md
"T2I_PEINTURE_GITEE_TOKENS": "gitee_xxx",
          "T2I_PEINTURE_MODELSCOPE_TOKENS": "ms_xxx",
          "T2I_PEINTURE_A4F_TOKENS": "",
          "T2I_PEINTURE_OPENAI_COMPATIBLE_URL": "https://api.siliconflow.cn/v1",
          "T2I_PEINTURE_OPENAI_COMPATIBLE_TOKENS": "sk_xxx,sk_yyy"
        }
      }

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · references/provider-endpoints.md (reported line 65)May include surrounding context.

md
"T2I_PEINTURE_GITEE_TOKENS": "gitee_xxx",
          "T2I_PEINTURE_MODELSCOPE_TOKENS": "ms_xxx",
          "T2I_PEINTURE_A4F_TOKENS": "",
          "T2I_PEINTURE_OPENAI_COMPATIBLE_URL": "https://api.siliconflow.cn/v1",
          "T2I_PEINTURE_OPENAI_COMPATIBLE_TOKENS": "sk_xxx,sk_yyy"
        }
      }

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document states that a fixed suffix requiring output language consistency is always appended, and that this mirrors behavior where a fixed language constraint is always applied. This is a natural-language locale policy concern because it describes enforced language behavior without mentioning any user opt-in, override, or language-selection mechanism.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The policy states that prompts may be automatically translated or optimized by sending them to third-party endpoints, including Pollinations and multiple provider chat-completions APIs, without any warning about data disclosure, sensitivity handling, or consent. In an image-generation skill, user prompts can contain proprietary, personal, or confidential information, so silent transmission to external services creates a real privacy and data-governance risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The reference documents multiple third-party endpoints that receive user prompts and bearer tokens, but it does not include any warning, consent requirement, or guidance on limiting sensitive data sent to those providers. In a skill that routes across several external image and chat services, this omission creates a real privacy and credential-handling risk because users or integrators may unknowingly transmit sensitive prompts and secrets outside their trust boundary.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The document specifies that gitee and modelscope reset by Beijing date (UTC+8), which is a locale-specific rule expressed in natural language. The file does not indicate user choice, opt-in, or a justification that this locale constraint is required for those providers.

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 · references/provider-endpoints.md (reported line 57)May include surrounding context.

md
POLLINATIONS_API_URL = "https://text.pollinations.ai/openai"
GITEE_CHAT_API_URL = "https://ai.gitee.com/v1/chat/completions"
MODELSCOPE_CHAT_API_URL = "https://api-inference.modelscope.cn/v1/chat/completions"
A4F_CHAT_API_URL = "https://api.a4f.co/v1/chat/completions"

FIXED_SYSTEM_PROMPT_SUFFIX = (
    "\nEnsure the output language matches the language of user's prompt that needs to be optimized."

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 · references/provider-endpoints.md (reported line 84)May include surrounding context.

md
POLLINATIONS_API_URL = "https://text.pollinations.ai/openai"
GITEE_CHAT_API_URL = "https://ai.gitee.com/v1/chat/completions"
MODELSCOPE_CHAT_API_URL = "https://api-inference.modelscope.cn/v1/chat/completions"
A4F_CHAT_API_URL = "https://api.a4f.co/v1/chat/completions"

FIXED_SYSTEM_PROMPT_SUFFIX = (
    "\nEnsure the output language matches the language of user's prompt that needs to be optimized."

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 · scripts/prompt_tools.py (reported line 16)May include surrounding context.

python
POLLINATIONS_API_URL = "https://text.pollinations.ai/openai"
GITEE_CHAT_API_URL = "https://ai.gitee.com/v1/chat/completions"
MODELSCOPE_CHAT_API_URL = "https://api-inference.modelscope.cn/v1/chat/completions"
A4F_CHAT_API_URL = "https://api.a4f.co/v1/chat/completions"

FIXED_SYSTEM_PROMPT_SUFFIX = (
    "\nEnsure the output language matches the language of user's prompt that needs to be optimized."

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 · scripts/provider_clients.py (reported line 32)May include surrounding context.

python
POLLINATIONS_API_URL = "https://text.pollinations.ai/openai"
GITEE_CHAT_API_URL = "https://ai.gitee.com/v1/chat/completions"
MODELSCOPE_CHAT_API_URL = "https://api-inference.modelscope.cn/v1/chat/completions"
A4F_CHAT_API_URL = "https://api.a4f.co/v1/chat/completions"

FIXED_SYSTEM_PROMPT_SUFFIX = (
    "\nEnsure the output language matches the language of user's prompt that needs to be optimized."

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

User prompt text is automatically sent to an external translation service without any notice, consent check, or sensitivity filtering. In an agent skill, prompts may contain confidential user data, so this creates a real privacy and data-governance risk even though the transmission is functionally intended.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

This line transmits user-supplied prompt text to Pollinations over the network for translation. External transmission is expected for the feature, but in a prompt-handling agent skill it is still a real privacy exposure if users are not informed or if sensitive data is included in prompts.

Content

Scanner excerpt · scripts/prompt_tools.py (reported line 96)May include surrounding context.

python
}

    try:
        response = requests.post(POLLINATIONS_API_URL, json=payload, timeout=timeout)
    except requests.RequestException as exc:
        raise PromptToolError(f"Translation request failed: {exc}")

Tainted flow: 'payload' from requests.post (line 196, 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 · scripts/prompt_tools.py (reported line 96)May include surrounding context.

python
}

    try:
        response = requests.post(POLLINATIONS_API_URL, json=payload, timeout=timeout)
    except requests.RequestException as exc:
        raise PromptToolError(f"Translation request failed: {exc}")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code sends user prompt content and bearer-authenticated requests to third-party provider APIs for optimization without any user-facing disclosure. While bearer tokens are sent in normal Authorization headers rather than leaked directly, the undisclosed transfer of user content to multiple external providers is a meaningful privacy/compliance issue in this skill context.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

This helper sends prompt contents to external optimization/chat providers, potentially across multiple services depending on routing. In this skill's context of free-quota token pooling and multi-provider fallback, the data-sharing surface is expanded, which increases the chance that user content reaches third parties unexpectedly.

Content

Scanner excerpt · scripts/prompt_tools.py (reported line 183)May include surrounding context.

python
def _chat_request(url: str, payload: Dict[str, object], headers: Dict[str, str], timeout: int, fallback: str) -> str:
    try:
        response = requests.post(url, json=payload, headers=headers, timeout=timeout)
    except requests.RequestException as exc:
        raise PromptToolError(f"Prompt optimization request failed: {exc}")

Tainted flow: 'payload' from requests.post (line 196, 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 · scripts/prompt_tools.py (reported line 183)May include surrounding context.

python
def _chat_request(url: str, payload: Dict[str, object], headers: Dict[str, str], timeout: int, fallback: str) -> str:
    try:
        response = requests.post(url, json=payload, headers=headers, timeout=timeout)
    except requests.RequestException as exc:
        raise PromptToolError(f"Prompt optimization request failed: {exc}")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code sends the user's image-generation prompt to external provider APIs and includes an Authorization bearer token, but the file provides no confirmation prompt, logging, or explanatory comment/docstring warning that user data and credentials are transmitted off-box. The same undisclosed pattern appears across multiple providers in this file, making the network-sharing behavior easy to miss for users or integrators.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.