Back to skill

Security audit

Bailian Studio

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its cloud media purpose, but its unvalidated endpoint overrides and upload/download paths could expose API credentials or private media if misconfigured or influenced.

Review this skill before installing. Use it only with non-sensitive images and text unless you accept that content being sent to Aliyun DashScope and, for local images, uploaded to OSS. Do not use untrusted DASHSCOPE_BASE_URL, --base-url, or OSS_ENDPOINT values; prefer the documented Aliyun HTTPS endpoints, narrowly scoped credentials, private buckets or short-lived URLs, and an isolated virtual environment with pinned dependencies.

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/image_generate.py:188
Finding

Unrestricted DashScope Endpoint Override Can Expose API Credentials and User Content

Content
View full analysis
str: return _get_value("DASHSCOPE_BASE_URL", env_path) or DEFAULT_BASE_URL ``` ```python # scripts/image_generate.py response = dashscope.MultiModalConversation.call( api_key=get_dashscope_key(env_path=env_path), model=model, messages=messages, result_format="message", stream=False, watermark=False, prompt_extend=True, negative_prompt=negative_prompt or DEFAULT_NEGATIVE_PROMPT, size=build_size(width, height), ) parser.add_argument( "--base-url", default=None, help="Override DashScope base URL", ) dashscope.base_http_api_url = ( args.base_url or get_region_base_url(env_path=args.config) ) ``` ```python # scripts/ocr_text.py resp = dashscope.MultiModalConversation.call( api_key=get_dashscope_key(), model=model, messages=messages, ocr_options={"task": "text_recognition"}, ) parser.add_argument("--base-url", default=None) if args.base_url: dashscope.base_http_api_url = args.base_url else: dashscope.base_http_api_url = get_region_base_url() ``` ```python # scripts/tts_speak.py resp = dashscope.audio.qwen_tts.SpeechSynthesizer.call( api_key=get_dashscope_key(), **kwargs, ) parser.add_argument("--base-url", default=None) if args.base_url: dashscope.base_http_api_url = args.base_url else: dashscope.base_http_api_url = get_region_base_url() ``` ### Technical Analysis The three service clients permit the DashScope base URL to be supplied through either a command-line argument or the `DASHSCOPE_BASE_URL` configuration value. The supplied URL is assign ...[truncated 1965 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/oss_upload.py:19
Finding

Arbitrary or Plaintext OSS Endpoints Can Receive Uploaded Local Files

Content
View full analysis
str: if endpoint.startswith("http://") or endpoint.startswith("https://"): return endpoint return f"https://{endpoint}" ``` ```python def upload_image(image_path: Path, object_key: Optional[str] = None) -> str: cfg = get_oss_config() access_key = cfg["access_key"] secret_key = cfg["secret_key"] bucket_name = cfg["bucket"] endpoint = cfg["endpoint"] image_path = Path(image_path) if not image_path.exists(): raise RuntimeError(f"Image not found: {image_path}") suffix = image_path.suffix or ".png" object_key = object_key or ( f"bailian-studio/{int(time.time())}-{image_path.stem}{suffix}" ) auth = oss2.Auth(access_key, secret_key) bucket = oss2.Bucket( auth, _normalize_endpoint(endpoint), bucket_name, ) bucket.put_object_from_file(object_key, str(image_path)) return _build_public_url(endpoint, bucket_name, object_key) ``` ### Technical Analysis The endpoint normalization function accepts an explicit `http://` URL unchanged. It also accepts any HTTPS hostname without checking that it belongs to the expected Aliyun OSS service. When local-image OCR or image-to-image generation is used, the path supplied by the caller is passed to `upload_image`, which uploads the entire file to that endpoint. The function verifies only that the path exists; it does not verify that it is a regular file, that its contents are an image, or that its size is reasonable. The OSS secret key is used locally to generate authentication data and is not necessarily transmitted verbatim. However, a hostile endpoint can receive the selected file, access-key identifiers, signed requests, metadata, and ...[truncated 1317 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/image_generate.py:119
Finding

Unvalidated API-Provided Media URLs Permit SSRF and Unbounded Downloads

Content
View full analysis
str: output = ( response.get("output") if isinstance(response, dict) else getattr(response, "output", None) ) if isinstance(output, dict): for key in ("results", "images"): items = output.get(key) if isinstance(items, list) and items: first = items[0] if isinstance(first, dict) and first.get("url"): return first["url"] choices = output.get("choices") if isinstance(choices, list) and choices: message = ( choices[0].get("message") if isinstance(choices[0], dict) else None ) content = ( message.get("content") if isinstance(message, dict) else None ) if isinstance(content, list): for item in content: if isinstance(item, dict) and item.get("image"): return item["image"] if output.get("url"): return output["url"] raise RuntimeError( f"Unexpected image generation response format: {response}" ) ``` ```python # scripts/image_generate.py def download_image(url: str, output_path: Path, timeout: int) -> Path: """Download an image URL to disk.""" response = requests.get(url, timeout=timeout) response.raise_for_status() ensure_parent(output_path) output_path.write_bytes(response.content) return output_path ``` ```python # scripts/tts_speak.py def _extract_audio_url(resp) -> str: try: return resp["o ...[truncated 3774 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unpinned Dependencies and Missing Integrity Verification Reduce Supply-Chain Security

Content
View full analysis
=1.24.0 oss2>=2.19.1 requests>=2.31.0 pytest>=8.0.0 ``` ### Technical Analysis All dependencies use open-ended minimum-version constraints. A future installation may therefore resolve to package versions that were not reviewed or tested with this project. The file also provides no cryptographic hashes to verify downloaded distributions. Python packages can execute code during installation, import, and normal runtime. If a future release is compromised, removed and replaced, or introduces insecure behavior, users following the documented installation command may execute it without any change to the audited repository. The package names are consistent with the libraries used by the source code. The audit found no suspicious package index, direct URL, obvious typo-squatting name, or confirmed malicious dependency. This finding concerns reproducibility and missing supply-chain hardening rather than evidence that the currently named packages are malicious. Including `pytest` in the runtime requirements also unnecessarily expands the production dependency set. ### Attack Path 1. A user runs the documented command `pip install -r requirements.txt`. 2. The package resolver selects the newest versions satisfying the lower bounds at installation time. 3. Those versions may differ from the versions originally reviewed and tested. 4. Installation or imported package code executes with the privileges of the user performing the installation. 5. If a selected release is compromised, the package can access files, credentials, environment variables, and network resources available to that user. ### Impact Assessment The potential impact is bounded by the privileges of the account installing or running the dependencies. If installation is performed as an adm ...[truncated 288 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

This documentation explicitly indicates that local images are uploaded to Alibaba Cloud OSS before being passed onward, but the top-level description does not make that data-transfer behavior prominent. Hidden or underemphasized third-party upload behavior is dangerous because users may provide sensitive local files believing processing is limited to DashScope or local execution.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This documentation explicitly indicates that local images are uploaded to Alibaba Cloud OSS before being passed onward, but the top-level description does not make that data-transfer behavior prominent. Hidden or underemphasized third-party upload behavior is dangerous because users may provide sensitive local files believing processing is limited to DashScope or local execution.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

This documentation explicitly indicates that local images are uploaded to Alibaba Cloud OSS before being passed onward, but the top-level description does not make that data-transfer behavior prominent. Hidden or underemphasized third-party upload behavior is dangerous because users may provide sensitive local files believing processing is limited to DashScope or local execution.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This documentation explicitly indicates that local images are uploaded to Alibaba Cloud OSS before being passed onward, but the top-level description does not make that data-transfer behavior prominent. Hidden or underemphasized third-party upload behavior is dangerous because users may provide sensitive local files believing processing is limited to DashScope or local execution.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

This documentation explicitly indicates that local images are uploaded to Alibaba Cloud OSS before being passed onward, but the top-level description does not make that data-transfer behavior prominent. Hidden or underemphasized third-party upload behavior is dangerous because users may provide sensitive local files believing processing is limited to DashScope or local execution.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/image_generate.py (reported line 170)May include surrounding context.

python
def read_prompt(prompt: Optional[str]) -> str:
    """Read prompt from argument or stdin."""
    if prompt and prompt.strip():
        return prompt.strip()
    if not sys.stdin.isatty():
        stdin_prompt = sys.stdin.read().strip()
        if stdin_prompt:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README explicitly states that local images are uploaded to OSS before OCR or image-to-image processing, and that generated files are written locally, but it does not clearly warn users about external data transmission, persistence, or possible sensitivity of uploaded content. This can lead users to unintentionally send confidential local images to a cloud service or leave generated outputs on disk without realizing the privacy and data-handling implications.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill documentation describes shell commands, environment-variable access, local file reads/writes, and network interactions, but it declares no explicit tool scope or permissions. In an agent setting, this creates an overbroad and under-specified capability surface, making it easier for the skill to access sensitive files, secrets, or external networks without clear user or platform constraints.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation states that local images are uploaded to OSS first, but it does not present this as a prominent warning near the user workflow. This is dangerous because users may unknowingly send sensitive local documents, screenshots, or personal images to third-party storage and downstream AI services, creating confidentiality and compliance risks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The image-to-image instructions show local reference image usage without an explicit warning that the file will be uploaded to external services. In this context, under-disclosure is especially risky because users often treat local creative assets as private, while the workflow transmits them off-device and may expose them through cloud storage or service logs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The design sends arbitrary user-provided text to an external Bailian TTS service but does not mention any user notice, consent, or data-handling warning. This can cause inadvertent disclosure of sensitive text if users assume synthesis is local, especially in a skill that reads from configurable environment-based integrations and is intended for easy command-line use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The plan explicitly sends user-provided text to an external TTS service but does not require any user-facing disclosure, consent prompt, or documentation warning that the text leaves the local environment. This can cause unintentional disclosure of sensitive prompts, secrets, or personal data if users assume the CLI is purely local audio playback.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

When a local image path is supplied, the code automatically uploads that file via upload_image() to obtain a remote URL for img2img. This implicit exfiltration of local file contents is risky because users may not realize a local image will leave their machine and be stored or processed by external infrastructure.

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 the user-provided prompt and any optional reference image to external services: DashScope for generation and potentially other remote endpoints for image handling. In a skill context, prompts and images may contain secrets, personal data, or proprietary material, and the CLI provides no explicit disclosure, confirmation, or data-classification guard before transmission.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

When a local image is provided, the script uploads that image to an external service and then submits it for OCR, but this file gives no user-facing disclosure, confirmation, or warning that image contents may leave the local environment. This can lead to unintended exfiltration of sensitive documents, IDs, screenshots, or regulated data, especially because OCR inputs often contain private text by design.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The helper constructs a public URL for uploaded content, and the surrounding upload flow can publish user-provided images to object storage without evidence of access controls or user consent. If sensitive or private images are processed, this can lead to unintended public exposure, link sharing, and long-lived data disclosure.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The file adds a generic OSS upload capability that is broader than the stated skill purpose of calling Bailian via DashScope for OCR, TTS, and image generation. This increases the skill's data-handling scope and creates a path for user images to be transferred to external storage, which can expose sensitive content and expand the attack surface beyond what a user would reasonably expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This function retrieves cloud credentials and transmits local image data to OSS over the network with no visible warning, prompt, or disclosure to the user. In a skill context, silent exfiltration of user-supplied media to third-party storage is risky because users may assume processing happens only through the described Bailian API path, not persistent external storage.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script sends arbitrary user-provided text to external DashScope TTS services and then fetches the resulting audio over the network without any user-facing disclosure at runtime. In a skill context, users may unknowingly submit sensitive prompts, secrets, or personal data to third-party services, creating privacy and compliance risk rather than code-execution risk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest frames the skill as a Bailian/DashScope integration for media capabilities. In addition to calling the TTS API, this file plays synthesized audio locally via ffplay and can write WAV output to an arbitrary path, which are extra host-interaction behaviors not conveyed by the description.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes a skill for calling Aliyun Bailian via DashScope to support OCR, TTS, and image generation/transformation. This script goes beyond generating speech by invoking the local ffplay executable to play audio on the host, which is a host-side execution capability rather than a direct Bailian API integration requirement.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/tts_speak.py (reported line 67)May include surrounding context.

python
tmp.write(wav_bytes)
        tmp.flush()
        try:
            subprocess.run(["ffplay", "-nodisp", "-autoexit", tmp.name], check=True)
        except FileNotFoundError:
            print("Error: ffplay not found. Please install ffmpeg.", file=sys.stderr)
            raise SystemExit(1)

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The natural-language instructions and sample prompts are Chinese-only, which can amount to a language policy issue when no user choice or rationale is provided. The file does not say the skill is intended only for a Chinese-speaking or region-specific audience, nor does it offer alternative language guidance.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The document presents the skill as a Chinese-language TTS feature and uses only Chinese text examples, but does not state that the tool is region-specific or that users may choose another language/locale. SQP-3 covers language or locale policy violations when a skill appears to force a specific language without user opt-in or justification.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dependency is specified with only a lower bound, so future installs may resolve to different versions over time. This weakens build reproducibility and can unintentionally introduce vulnerable or breaking upstream releases into the skill.

Content

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

text
dashscope>=1.24.0
oss2>=2.19.1
requests>=2.31.0
pytest>=8.0.0