Back to skill

Security audit

Qwen Skill

Security checks for vulnerabilities and agentic risk

Overview

This skill performs the promised image generation, but it can send your API key, prompts, and selected images to a configurable endpoint and downloads unvalidated response URLs.

Install only if you trust the publisher and will run it in a controlled directory. Avoid untrusted project folders with .env files, do not set DASHSCOPE_ENDPOINT unless you control and trust that server, and assume prompts plus selected input images are uploaded to the configured endpoint and saved locally afterward.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/qwen_image.py:409
Finding

Arbitrary API Endpoint Can Receive DashScope Credentials and Private Image Data

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/qwen_image.py:166
Finding

Unvalidated Response URLs Permit SSRF and Unbounded Content Downloads

Content
View full analysis
list[str]: out_dir.mkdir(parents=True, exist_ok=True) timestamp = dt.datetime.now().strftime("%Y%m%d-%H%M%S") files = [] for idx, url in enumerate(urls, start=1): path = out_dir / f"qwen-{timestamp}-{idx:02d}.png" resp = requests.get(url, timeout=300) resp.raise_for_status() path.write_bytes(resp.content) files.append(str(path)) return files ``` The publishing fallback contains the same behavior: ```python for idx, url in enumerate(urls, start=1): dst = publish_dir / f"qwen-{timestamp}-{idx:02d}.png" resp = requests.get(url, timeout=300) resp.raise_for_status() dst.write_bytes(resp.content) published_files.append(str(dst)) ``` A separate helper also performs an unrestricted fetch: ```python def fetch_url_bytes(url: str) -> bytes: resp = requests.get(url, timeout=180) resp.raise_for_status() return resp.content ``` ### Technical Analysis Image URLs obtained from an API response are treated as trusted. Before issuing `GET` requests, the script does not validate: - The URL scheme. - The destination hostname or resolved IP address. - Whether the address is loopback, private, link-local, or reserve ...[truncated 2241 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unpinned Dependencies Reduce Build Integrity and Reproducibility

Content
View full analysis
=2.31.0 Pillow>=10.0.0 ``` The documented installation command resolves these unconstrained upper versions: ```bash pip3 install -r {baseDir}/requirements.txt ``` ### Technical Analysis Both dependencies use minimum-version constraints without exact versions or package hashes. Consequently, separate installations can retrieve different package releases, including releases published after the Skill was audited. No malicious, typosquatted, or dependency-confusion package was identified: `requests` and `Pillow` are established package names. The issue is therefore supply-chain hardening and reproducibility rather than evidence that the current dependencies are malicious. Without a lock file or integrity hashes, the installed code is not necessarily identical to the code tested by the Skill author. A compromised upstream release, compromised package-index account, or newly incompatible version satisfying the lower bound could alter installation or runtime behavior. ### Attack Path 1. A new or compromised release of `requests` or `Pillow` is published and satisfies the stated minimum version. 2. A user later runs: ```bash pip3 install -r requirements.txt ``` 3. The package resolver selects that unreviewed release. 4. The package executes installation or runtime code with the permissions of the user running the Skill. 5. A malicious release could access data available to that process, including files, environment variables, and network resources. This is a general supply-chain path; the audit found no evidence that the currently named packages or versions are malicious. ### Impact Assessment If an upstream package release were compromised, code could execute with the same operating-system privileges as the Skill process. That scope could include access to th ...[truncated 291 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (21)

Tainted flow: 'api_key' from os.getenv (line 489, 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 · scripts/qwen_image.py (reported line 148)May include surrounding context.

python
if size:
        payload["parameters"]["size"] = size

    response = requests.post(
        endpoint,
        headers={
            "Authorization": f"Bearer {api_key}",

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared purpose frames the skill narrowly as image generation/editing, but the instructions and referenced behavior include additional capabilities: fetching arbitrary URLs, downloading and republishing files, creating HTML viewer pages, loading .env configuration, and emitting channel-specific payload conventions. This mismatch increases the chance that reviewers or users underappreciate the skill's data movement and persistence behavior, which can enable SSRF-like fetching, unintended publication of content, or exposure of local deployment details.

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

md
- First use `read` on this `SKILL.md`, then execute the Python command below.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- First use `read` on this `SKILL.md`, then execute the Python command below.

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

Or use .env (auto-loaded from current directory, then {baseDir}):

bash
cat > .env <<'EOF'
DASHSCOPE_API_KEY=your_api_key
DASHSCOPE_REGION=sg
OPENCLAW_MEDIA_OUTBOUND_DIR=~/.openclaw/media/outbound

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

python
Or use `.env` (auto-loaded from current directory, then `{baseDir}`):

```bash
cat > .env <<'EOF'
DASHSCOPE_API_KEY=your_api_key
DASHSCOPE_REGION=sg
OPENCLAW_MEDIA_OUTBOUND_DIR=~/.openclaw/media/outbound

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

python
Or use `.env` (auto-loaded from current directory, then `{baseDir}`):

```bash
cat > .env <<'EOF'
DASHSCOPE_API_KEY=your_api_key
DASHSCOPE_REGION=sg
OPENCLAW_MEDIA_OUTBOUND_DIR=~/.openclaw/media/outbound

Credential Access

High
Category
Privilege Escalation
Confidence
80% confidence
Finding

The script automatically reads .env from the current working directory, which is less trusted than the application directory and can enable environment poisoning if the tool is run inside an attacker-controlled folder. An attacker could supply a malicious .env to redirect endpoints or swap credentials, causing unintended data egress or account misuse.

Content

Scanner excerpt · scripts/qwen_image.py (reported line 81)May include surrounding context.

python
def resolve_dotenv_paths() -> list[Path]:
    candidates = [
        Path.cwd() / ".env",
        Path(__file__).resolve().parent.parent / ".env",
    ]
    dedup = []

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

python
def resolve_dotenv_paths() -> list[Path]:
    candidates = [
        Path.cwd() / ".env",
        Path(__file__).resolve().parent.parent / ".env",
    ]
    dedup = []
    seen = 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 · scripts/qwen_image.py (reported line 557)May include surrounding context.

python
def resolve_dotenv_paths() -> list[Path]:
    candidates = [
        Path.cwd() / ".env",
        Path(__file__).resolve().parent.parent / ".env",
    ]
    dedup = []
    seen = set()

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill exposes capabilities consistent with environment access, file read/write, and network use, but does not declare any explicit tool scope or allowed-tools boundary. In a skill system, this weakens reviewability and enforcement, making it easier for the skill to perform side effects the caller may not expect, especially when combined with external API calls and filesystem publishing.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The instructions require that failures be reported in exactly two short Chinese sentences. This forces a specific language regardless of the user's language preference, and the file does not offer any opt-in, fallback, or region-specific justification for the constraint.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

The script transmits user prompts and possibly image content to an external service. While this is core functionality, it is still a real data egress path and becomes security-relevant because the skill also supports local-file ingestion and optional endpoint override, which can increase the chance of sensitive data leaving the host unexpectedly.

Content

Scanner excerpt · scripts/qwen_image.py (reported line 148)May include surrounding context.

python
if size:
        payload["parameters"]["size"] = size

    response = requests.post(
        endpoint,
        headers={
            "Authorization": f"Bearer {api_key}",

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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 · scripts/qwen_image.py (reported line 409)May include surrounding context.

python
parser.add_argument("--n", type=int, default=1, help="number of output images, range [1,6]")
    parser.add_argument("--size", default="", help='optional size like "1024*1024"')
    parser.add_argument("--negative-prompt", default=" ", help="negative prompt")
    parser.add_argument("--no-prompt-extend", action="store_true", help="disable prompt extension")
    parser.add_argument("--watermark", action="store_true", help="enable output watermark")
    parser.add_argument("--out-dir", default="./tmp/qwen-image", help="directory to save downloaded images")
    parser.add_argument(

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Several reply strings and help text explicitly specify or emit Chinese output such as 'Chinese text + markdown image URL' and '已为你生成图片。' regardless of user preference. This forces a specific language in natural-language output without any opt-in or locale 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 script sends prompts and, in img2img mode, user-supplied images to a third-party remote API without any explicit runtime disclosure or consent mechanism. In a skill context, users may assume local processing, so silent external transmission can expose sensitive images or prompt content to the provider.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency specifier requests>=2.31.0 is unpinned, so builds may resolve to different versions over time and can inadvertently pick up a vulnerable or breaking release. In a skill that likely performs network access, this weakens supply-chain reproducibility and makes it harder to verify whether a safe version is installed.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.31.0
Pillow>=10.0.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
88% confidence
Finding

requests has multiple known advisories, and because the manifest does not pin an exact version, it is impossible to determine from this file alone whether an affected release will be installed. In a network-enabled skill, that uncertainty increases risk because dependency resolution may select a vulnerable version in some environments.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency specifier Pillow>=10.0.0 is unpinned, which means installations are not reproducible and may drift to versions with new vulnerabilities or incompatible behavior. Because this skill handles image generation or editing, Pillow is security-relevant and malformed-image attack surface makes version control important.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
requests>=2.31.0
Pillow>=10.0.0

Unverifiable Dependency: Pillow has 16 known advisory(ies) (CVE-2016-2533 (Pillow buffer overflow in ImagingPcdDecode); CVE-2023-50447 (Arbitrary Code Execution in Pillow); CVE-2021-27922 (Pillow Uncontrolled Resource Consumption) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding

Pillow has a history of security advisories, and the unpinned requirement prevents verification that deployments will use a non-vulnerable release. Since this skill processes images, any vulnerable image-parsing library is especially relevant due to risks such as denial of service or potentially worse parser flaws.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script automatically downloads and republishes generated images into local output and outbound publish directories, potentially creating persistent artifacts without clear disclosure. In shared or multi-user environments, this can unintentionally retain or expose generated content longer than expected.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.