Back to skill

Security audit

ModelScope AI Image Generator

Security checks for vulnerabilities and agentic risk

Overview

This image-generation skill matches its stated purpose, but it needs Review because it handles and persists API keys in ways that can expose them locally.

Install only if you are comfortable with ModelScope receiving your image prompts and with the skill using a ModelScope API key. Prefer an environment variable or secret manager, avoid passing keys on the command line, avoid --save-key unless you manually protect the file permissions, and do not include sensitive or regulated information in prompts.

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

Warning
Location
scripts/generate.py:62
Finding
API Key Stored Without Enforced Restrictive Permissions on POSIX Systems## Vulnerability Details **File Location**: `scripts/generate.py`, lines 62–68 **Vulnerability Type**: Insecure plaintext credential storage **Risk Level**: Medium ```python CONFIG_DIR.mkdir(parents=True, exist_ok=True) CONFIG_FILE.write_text(api_key) # Windows 下设置文件权限为仅当前用户可读 if sys.platform == "win32": import stat os.chmod(CONFIG_FILE, stat.S_IREAD | stat.S_IWRITE) ``` ### Technical Analysis The `--save-key` function writes the ModelScope API key in plaintext to `~/.modelscope/api_key`. Restrictive permissions are attempted only on Windows. On POSIX systems, the resulting permissions depend on the process umask. With commonly used settings, the file may be created with mode `0644`, allowing other local users to read it. The configuration directory may also be created with mode `0755`. Persisting the credential is not required for image generation and therefore exceeds the minimum credential-handling privileges necessary for the core function. Although this is not covert credential exfiltration, it creates an avoidable local disclosure risk. ### Attack Path 1. A user invokes the script with `--save-key`. 2. The script creates `~/.modelscope/api_key` and writes the token in plaintext. 3. On a POSIX system with a permissive umask, the file remains readable by other local accounts or processes. 4. An attacker with local filesystem access reads the token. 5. The attacker submits authenticated requests to ModelScope using the victim's credential. ### Impact Assessment An attacker could obtain the user's ModelScope API key and exercise the API permissions associated with it. This may allow unauthorized image-generation requests, consumption of account quota, access to resources available to the token, and activity attributed to the victim. This issue does not independently provide operating-system privilege escalation.
Remediation
## Remediation Suggestions - Prefer an operating-system credential manager rather than a plaintext file. - On POSIX systems, create `~/.modelscope` with mode `0700`. - Create the credential file atomically with mode `0600`, rather than relying on the user's umask. - Explicitly verify and correct existing file permissions before reading or writing the credential. - Avoid following symbolic links when creating or replacing the credential file. - Document how users can revoke and rotate a potentially exposed ModelScope token.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate.py:165
Finding
API Keys Accepted and Recommended Through Command-Line Arguments## Vulnerability Details **File Location**: `scripts/generate.py`, lines 165–166; also documented in `SKILL.md`, lines 15, 29, and 50 **Vulnerability Type**: Credential exposure through process arguments and shell history **Risk Level**: Medium ```python parser.add_argument("--api-key", help="API Key") parser.add_argument("--save-key", metavar="KEY", help="保存 API Key 到配置文件") ``` The documentation recommends a command containing the credential: ```bash py scripts/generate.py --save-key 你的密钥 ``` ### Technical Analysis Secrets supplied as command-line arguments may be recorded in shell history, terminal session logs, process-monitoring systems, diagnostic reports, or automation logs. Depending on the operating system and local configuration, command-line arguments may also be visible to other users while the process is running. The script supports environment-based credential loading, so exposing the key through an argument is not necessary for the declared image-generation functionality. Actively documenting `--save-key KEY` increases the likelihood that users will disclose credentials through command history. ### Attack Path 1. A user follows the documentation and invokes `--api-key TOKEN` or `--save-key TOKEN`. 2. The shell records the complete command in its history, or a process-monitoring facility captures the argument list. 3. A local attacker, administrator, monitoring operator, or compromised process retrieves the recorded command. 4. The attacker extracts the token and authenticates to ModelScope as the victim. ### Impact Assessment Exposure grants the attacker the ModelScope API privileges assigned to the stolen token. Potential consequences include unauthorized API usage, quota or billing consumption, access to token-authorized resources, and actions attributed to the victim. The scope is limited to the privileges of the exposed API key and does not directly grant system-level privileges.
Remediation
## Remediation Suggestions - Remove secret-bearing command-line options where practical. - Read credentials from an interactive prompt using hidden input, an environment variable, standard input, or an operating-system credential store. - If CLI options must remain for compatibility, clearly warn that they can expose secrets and discourage their use. - Replace the documented `--save-key TOKEN` workflow with an interactive setup command that securely prompts for the key. - Advise affected users to remove exposed commands from shell history and rotate any token previously passed on the command line.

T08 · Insecure Dependencies

Note
Location
SKILL.md:58
Finding
Third-Party Dependencies Installed Without Version or Integrity Pinning## Vulnerability Details **File Location**: `SKILL.md`, line 58 **Vulnerability Type**: Unpinned third-party dependencies **Risk Level**: Low ```bash pip install requests pillow ``` ### Technical Analysis The installation instructions retrieve the latest available versions of `requests`, `pillow`, and their transitive dependencies without fixed versions or integrity hashes. Consequently, installations are not reproducible and the exact code executed can change after the Skill has been reviewed. The package names are legitimate and the documentation does not specify a suspicious package index or dependency source. Therefore, this finding represents supply-chain hardening weakness rather than evidence that the Skill intentionally introduces a malicious dependency. ### Attack Path 1. A user runs the documented `pip install requests pillow` command. 2. The package index resolves versions available at installation time. 3. A compromised, malicious, or unexpectedly vulnerable future package release is selected. 4. Package installation hooks or imported runtime code execute with the privileges of the user running the command. 5. The compromised dependency may access files, environment variables, network resources, or API credentials available to that user. ### Impact Assessment A malicious dependency release could execute arbitrary code with the installing user's privileges. This could expose the ModelScope API key, modify user-owned files, or access other resources available to the environment. The practical likelihood is reduced because the named packages are established packages and no unsafe source is explicitly configured.
Remediation
## Remediation Suggestions - Pin reviewed direct and transitive dependency versions in a lock file. - Include cryptographic hashes and install with hash verification. - Regularly update pinned versions after vulnerability and compatibility review. - Install dependencies inside an isolated virtual environment. - Use the official package index over HTTPS and avoid untrusted mirrors. - Add automated dependency vulnerability and integrity scanning to the release process.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (10)

Tainted flow: 'headers' from os.environ.get (line 83, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
payload["loras"] = loras
    
    # 发起异步请求
    resp = requests.post(
        f"{BASE_URL}v1/images/generations",
        headers={**headers, "X-ModelScope-Async-Mode": "true"},
        data=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.environ.get (line 83, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
# 轮询状态
    max_attempts = 60
    for i in range(max_attempts):
        result = requests.get(
            f"{BASE_URL}v1/tasks/{task_id}",
            headers={**headers, "X-ModelScope-Task-Type": "image_generation"},
        )
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Lp3

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding
The skill documentation describes capabilities that involve environment variables, local file reads/writes, shell execution, and outbound network access, but it does not declare any tool scope or permission boundaries. This increases the risk of overprivileged execution because an agent may invoke the skill with broader capabilities than necessary, making misuse or accidental data exposure more likely.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The trigger conditions include broad everyday phrases like '生成图片', '画图', and 'generate image', which can cause the skill to activate in contexts the user did not intend. Over-broad activation is dangerous because it can send user prompts to an external service unexpectedly or cause the agent to choose this skill when a safer or local option would have been more appropriate.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill explains how to provide prompts and API keys but does not clearly warn that user prompts and credentials will be transmitted to the external ModelScope service. This is a real privacy and security issue because users may unknowingly disclose sensitive text, and passing API keys via command-line arguments can also expose secrets through shell history or process inspection.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The file’s natural-language documentation is presented in Chinese, and the CLI description/help strings continue that language choice throughout the script. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly justified, which is not present here.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The manifest describes a skill for generating images via ModelScope with model and LoRA options. However, this code adds a separate capability to store credentials persistently under ~/.modelscope/api_key, which is not part of image generation itself and expands the skill into local secret management.

Tainted flow: 'task_id' from requests.post (line 103, network input) → requests.get (network output)

Medium
Category
Data Flow
Content
# 轮询状态
    max_attempts = 60
    for i in range(max_attempts):
        result = requests.get(
            f"{BASE_URL}v1/tasks/{task_id}",
            headers={**headers, "X-ModelScope-Task-Type": "image_generation"},
        )
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.

Tainted flow: 'image_url' from requests.get (line 120, network input) → requests.get (network output)

Medium
Category
Data Flow
Content
image_url = data["output_images"][0]
            print(f"下载图片: {image_url}")
            
            img_resp = requests.get(image_url)
            img_resp.raise_for_status()
            
            image = Image.open(BytesIO(img_resp.content))
Confidence
87% confidence
Finding
The script downloads image content from image_url supplied by the remote API without validating the scheme, host, or content type. If the upstream service is compromised or returns attacker-controlled URLs, this can be abused as an SSRF-like outbound fetch primitive and may also expose the process to malicious image payloads via Pillow parsing.

Context-Inappropriate Capability

Low
Confidence
79% confidence
Finding
The manifest focuses on generating images, but get_api_key searches CLI input, MODELSCOPE_API_KEY, and a local file in the user's home directory. While needed for authentication, scanning multiple local secret sources is an additional capability that is not described in the manifest.

Static analysis

No suspicious patterns detected.