Back to skill

Security audit

Alibaba Cloud Bailian Qwen Image 2.0 image generation. Supports text-to-image and image-to-image (reference image + text). For product promotion image generation, e-commerce image editing, marketing material creation. Provides Python API, CLI tool, and ComfyUI custom nodes.

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a real Alibaba Bailian image-generation integration, but it handles credentials too broadly and can send the API key to an unvalidated image-download URL returned by the service.

Review before installing. Use a dedicated, low-privilege DashScope API key with spending limits, avoid storing unrelated secrets in nearby .env files, and do not submit sensitive prompts or images unless Alibaba Cloud processing is acceptable. The highest priority fixes are to validate image download hosts, avoid attaching Authorization to arbitrary returned URLs, and load only DASHSCOPE_API_KEY from an explicit configuration source.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/bailian_image_gen.py:153
Finding

DashScope API Credential Sent to an Unvalidated Response-Controlled URL

Content
View full analysis

Vulnerability Details

File Location: scripts/bailian_image_gen.py:153-155, scripts/comfyui_bailian_node.py:91-93, and scripts/comfyui_bailian_node.py:157-159
Vulnerability Type: Credential disclosure through an unvalidated outbound destination
Risk Level: Medium

Vulnerable Code

scripts/bailian_image_gen.py:152-161:

python
def download_image(self, image_url: str, output_path: str) -> str:
    headers = {"Authorization": f"Bearer {self.api_key}"}
    response = requests.get(image_url, headers=headers, timeout=60)
    response.raise_for_status()
    
    with open(output_path, "wb") as f:
        f.write(response.content)
    
    return output_path

scripts/comfyui_bailian_node.py:86-93:

python
print(f"[BailianNode] Image URL: {image_url[:60]}...")

import requests
headers = {"Authorization": f"Bearer {client.api_key}"}
img_response = requests.get(image_url, headers=headers, timeout=60)
img_response.raise_for_status()

scripts/comfyui_bailian_node.py:152-159:

python
print(f"[BailianNode] Image URL: {image_url[:60]}...")

import requests
headers = {"Authorization": f"Bearer {client.api_key}"}
img_response = requests.get(image_url, headers=headers, timeout=60)
img_response.raise_for_status()

Technical Analysis

The image URL is extracted from a remote API response without validating its scheme, hostname, port, or resolved address. The code then sends the DashScope bearer credential to that URL in an Authorization header.

Consequently, the credential is not restricted to the intended Alibaba Cloud service boundary. If the API response is compromised or otherwise contains a malicious URL, the client can send the API key to an attacker-controlled server. A URL resolving to a loopback, link-local, or private address could also cause a server-side request forgery-style request from the host running the Skill.

Downloading generated ...[truncated 1558 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse returned URLs with urllib.parse.urlsplit.
  2. Require the https scheme and reject embedded credentials, unexpected ports, fragments, malformed hostnames, and non-absolute URLs.
  3. Maintain an explicit allowlist of documented Alibaba Cloud image-delivery hostnames. Compare normalized hostnames exactly or use carefully bounded subdomain checks.
  4. Resolve the hostname and reject loopback, private, link-local, multicast, reserved, and unspecified IP addresses. Revalidate redirects and DNS resolution to reduce redirect and DNS-rebinding risks.
  5. Disable automatic redirects or validate every redirect target before following it.
  6. Attach the bearer token only when the validated destination is documented to require DashScope authentication. Otherwise, download the signed URL without an Authorization header.
  7. Centralize image downloading in the hardened download_image() method so the two ComfyUI nodes do not duplicate unsafe request logic.
  8. Apply response-size and content-type limits before loading or writing downloaded data.

T05 · Unauthorized Access and Privilege Escalation

Note
Location
scripts/comfyui_bailian_node.py:17
Finding

Overbroad Loading of Shared Environment Files into the Process Environment

Content
View full analysis

Vulnerability Details

File Location: scripts/bailian_image_gen.py:17-27 and scripts/comfyui_bailian_node.py:17-36
Vulnerability Type: Excessive secret access and process-environment exposure
Risk Level: Low

Vulnerable Code

scripts/bailian_image_gen.py:17-27:

python
def load_env_file():
    """Load environment variables from .env file"""
    env_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), '.env')
    if os.path.exists(env_path):
        with open(env_path, 'r', encoding='utf-8') as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith('#') and '=' in line:
                    key, value = line.split('=', 1)
                    os.environ.setdefault(key.strip(), value.strip())

load_env_file()

scripts/comfyui_bailian_node.py:17-38:

python
def load_env_file():
    """Load environment variables from .env file"""
    possible_paths = [
        os.path.join(current_dir, '.env'),
        os.path.join(os.path.dirname(current_dir), '.env'),
        os.path.join(os.path.dirname(os.path.dirname(current_dir)), '.env'),
    ]
    
    for env_path in possible_paths:
        if os.path.exists(env_path):
            with open(env_path, 'r', encoding='utf-8') as f:
                for line in f:
                    line = line.strip()
                    if line and not line.startswith('#') and '=' in line:
                        key, value = line.split('=', 1)
                        key = key.strip()
                        value = value.strip()
                        if key and value and key not in os.environ:
                            os.environ[key] = value
            print(f"[BailianNode] Loaded .env: {env_path}")
            return

load_env_file()

Technical Analysis

The Skill only requires DASHSCOPE_API_KEY, but both loaders ...[truncated 1946 chars]

Remediation
View remediation

Remediation Suggestions

  1. Read only the required DASHSCOPE_API_KEY entry instead of importing every assignment.
  2. Store the selected value directly on the client rather than copying unrelated configuration into os.environ.
  3. Use one explicit, documented configuration path. Do not search parent or grandparent directories automatically.
  4. Allow operators to provide an explicit environment-file path through trusted configuration when file-based loading is required.
  5. Validate file ownership and permissions before reading a credential file, and recommend restrictive filesystem permissions.
  6. Avoid logging the path to a potentially sensitive shared configuration file unless diagnostic logging is explicitly enabled.
  7. Prefer the already-set DASHSCOPE_API_KEY environment variable and perform no filesystem search when it is present.
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (27)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

export DASHSCOPE_API_KEY=your-api-key

text

Get API Key from  bailian.console.aliyun.com

### Command Line Usage

Credential Access

High
Category
Privilege Escalation
Confidence
71% confidence
Finding

The documentation instructs users to write a plaintext API key directly into /path/to/ComfyUI/.env, which may reside in a broad-access application directory and can be left readable by other local users, plugins, backups, or accidental sync processes. While not malicious, this increases credential exposure risk in shared or plugin-heavy environments like ComfyUI.

Content

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

  1. Configure API Key in ComfyUI directory:

    bash
    echo "DASHSCOPE_API_KEY=your-api-key" > /path/to/ComfyUI/.env
    
  2. Restart ComfyUI

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

md
sys.path.insert(0, current_dir)

def load_env_file():
    """Load environment variables from .env file"""
    possible_paths = [
        os.path.join(current_dir, '.env'),
        os.path.join(os.path.dirname(current_dir), '.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 · SKILL.md (reported line 38)May include surrounding context.

md
sys.path.insert(0, current_dir)

def load_env_file():
    """Load environment variables from .env file"""
    possible_paths = [
        os.path.join(current_dir, '.env'),
        os.path.join(os.path.dirname(current_dir), '.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 · SKILL.md (reported line 39)May include surrounding context.

md
sys.path.insert(0, current_dir)

def load_env_file():
    """Load environment variables from .env file"""
    possible_paths = [
        os.path.join(current_dir, '.env'),
        os.path.join(os.path.dirname(current_dir), '.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 · SKILL.md (reported line 184)May include surrounding context.

md
sys.path.insert(0, current_dir)

def load_env_file():
    """Load environment variables from .env file"""
    possible_paths = [
        os.path.join(current_dir, '.env'),
        os.path.join(os.path.dirname(current_dir), '.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/bailian_image_gen.py (reported line 20)May include surrounding context.

python
sys.path.insert(0, current_dir)

def load_env_file():
    """Load environment variables from .env file"""
    possible_paths = [
        os.path.join(current_dir, '.env'),
        os.path.join(os.path.dirname(current_dir), '.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/comfyui_bailian_node.py (reported line 18)May include surrounding context.

python
sys.path.insert(0, current_dir)

def load_env_file():
    """Load environment variables from .env file"""
    possible_paths = [
        os.path.join(current_dir, '.env'),
        os.path.join(os.path.dirname(current_dir), '.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/comfyui_bailian_node.py (reported line 199)May include surrounding context.

python
sys.path.insert(0, current_dir)

def load_env_file():
    """Load environment variables from .env file"""
    possible_paths = [
        os.path.join(current_dir, '.env'),
        os.path.join(os.path.dirname(current_dir), '.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/bailian_image_gen.py (reported line 21)May include surrounding context.

python
def load_env_file():
    """Load environment variables from .env file"""
    possible_paths = [
        os.path.join(current_dir, '.env'),
        os.path.join(os.path.dirname(current_dir), '.env'),
        os.path.join(os.path.dirname(os.path.dirname(current_dir)), '.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/comfyui_bailian_node.py (reported line 20)May include surrounding context.

python
def load_env_file():
    """Load environment variables from .env file"""
    possible_paths = [
        os.path.join(current_dir, '.env'),
        os.path.join(os.path.dirname(current_dir), '.env'),
        os.path.join(os.path.dirname(os.path.dirname(current_dir)), '.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/comfyui_bailian_node.py (reported line 21)May include surrounding context.

python
def load_env_file():
    """Load environment variables from .env file"""
    possible_paths = [
        os.path.join(current_dir, '.env'),
        os.path.join(os.path.dirname(current_dir), '.env'),
        os.path.join(os.path.dirname(os.path.dirname(current_dir)), '.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/comfyui_bailian_node.py (reported line 22)May include surrounding context.

python
def load_env_file():
    """Load environment variables from .env file"""
    possible_paths = [
        os.path.join(current_dir, '.env'),
        os.path.join(os.path.dirname(current_dir), '.env'),
        os.path.join(os.path.dirname(os.path.dirname(current_dir)), '.env'),
    ]

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill documents capabilities that require environment access, file reads, and outbound network access, but it does not declare any explicit tool scope or permissions boundary. This increases the chance that an agent runtime grants broader access than users expect, especially since the skill sends prompts and images to an external service and reads local reference images.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill description explains image generation features but does not clearly warn that user prompts and reference images are transmitted to Alibaba Cloud. This creates a privacy and data-handling risk because users may provide sensitive text or local images without informed consent about external processing.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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/bailian_image_gen.py (reported line 103)May include surrounding context.

python
if n: payload["parameters"]["n"] = n
            if seed is not None: payload["parameters"]["seed"] = seed
        
        response = requests.post(url, headers=self.headers, json=payload, timeout=120)
        response.raise_for_status()
        return response.json()

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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/bailian_image_gen.py (reported line 131)May include surrounding context.

python
if n: payload["parameters"]["n"] = n
            if seed is not None: payload["parameters"]["seed"] = seed
        
        response = requests.post(url, headers=self.headers, json=payload, timeout=120)
        response.raise_for_status()
        return response.json()

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The node automatically searches for and loads .env files from its own directory and two parent directories, which broadens access to secrets beyond what is needed for normal image-generation behavior. In a plugin context, this can unexpectedly ingest unrelated credentials from a larger application or user workspace and makes secret exposure more likely if the imported module or logs mishandle environment variables.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The node sends prompts and, in image-to-image mode, user images to an external Bailian service, but the code provides no explicit consent or warning at the point of use. In creative tooling, prompts and reference images may contain proprietary or personal data, so silent transmission 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
95% confidence
Finding

The image-to-image flow writes the input image to a named temporary file on disk without disclosing that local persistence occurs. Even though the file is later deleted, sensitive images may briefly exist on disk and could be recovered by other processes, backups, or from failure paths on shared systems.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

This is a JSON manifest/workflow file, so vague-trigger rules apply. The instructions describe invocation in a generic way and do not provide any scope, exclusions, or unique trigger phrasing tied to this specific skill, which could make activation expectations ambiguous in environments with multiple queued workflows.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
68% confidence
Finding

The natural-language note explicitly directs users to configure a provider-specific API key. While not severe, it imposes a specific external service requirement in the instructions without clarifying whether alternatives exist or whether this provider constraint is required for a documented reason.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency specification uses a lower-bound only constraint for requests, which makes builds non-reproducible and can pull in different versions over time. This becomes a security concern because vulnerable or behavior-changing releases may be installed without review, and the accompanying SC4 finding shows this package family has multiple known advisories.

Content

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

text
requests>=2.28.0
Pillow>=9.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

Because requests is not pinned, there is no assurance that deployments will avoid versions affected by known advisories such as credential leakage or TLS/verification-related flaws. In a skill that likely makes outbound API calls to Alibaba Cloud, this can expose secrets, request metadata, or weaken transport security depending on the resolved version.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The Pillow dependency is also unpinned, so installations may resolve to different versions depending on time and environment. For an image-generation skill that processes image inputs, this is more sensitive than usual because image libraries are frequently targeted with parsing and resource-consumption flaws.

Content

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

text
requests>=2.28.0
Pillow>=9.0.0

Static analysis

No suspicious patterns detected.