Back to skill

Security audit

AIGC服饰电商图生成专家

Security checks for vulnerabilities and agentic risk

Overview

This clothing image-generation skill has a coherent purpose, but it needs review because it handles credentials, public uploads, and local script execution with weak scoping and contains unsafe default model-selection rules.

Install only if you are comfortable with LinkFox receiving prompts, image URLs, and account credentials, and review the credential setup carefully. Avoid storing the API key in shell startup files, do not use endpoint override environment variables in normal use, upload only files that may become public, and do not run pipeline jobs or state files from untrusted sources.

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
skills/linkfox-aigc-imagegen/scripts/onboarding.py:454
Finding

API credentials are exposed through stdout and persisted in plaintext shell configuration

Content
View full analysis
dict: hdr = _headers("agent-linkfox-web", "ai.linkfox.com", access_token=access_token, user_id=user_id, group_id=group_id) for path, source in (("/group/getApiToken", "existing"), ("/group/generateApiToken", "generated")): resp = _http_post(f"{_agent_user_base()}{path}", {"id": group_id}, hdr) if "_error" in resp: return {"error": f"{path.rsplit('/', 1)[-1]}: {resp.get('_body') or resp['_error']}"} tok = _extract_token(resp) if tok: return {"api_key": tok, "source": source} return {"error": f"generateApiToken: 未拿到 token,响应: {json.dumps(resp, ensure_ascii=False)}"} def login_and_get_key(phone: str, code: str, channel: str) -> dict: masked = _mask_phone(phone) if not re.fullmatch(r"\d{11}", phone): return {"error": f"login: 手机号格式不正确: {phone}", "phone": masked} if not re.fullmatch(r"\d{4,8}", code): return {"error": f"login: 验证码格式不正确: {code}", "phone": masked} lg = _login_v3(phone, code, channel) if "error" in lg: return {"error": lg["error"], "phone": masked} if lg.get("is_new_user"): lbt = _login_by_token(lg["access_token"], lg["refresh_token"]) if "error" in lbt: print(f"{T ...[truncated 3555 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
skills/linkfox-aigc-imagegen/scripts/aigc_imagegen.py:38
Finding

Unrestricted gateway overrides can redirect bearer credentials and user data to an attacker-controlled server

Content
View full analysis
str: return _env_base("LINKFOX_AGENT_API_URL", "https://tool-gateway.linkfox.com", "LINKFOX_TOOL_GATEWAY") def _login_base() -> str: return _env_base("LINKFOX_LOGIN_API_URL", "https://api.linkfox.com") def _agent_user_base() -> str: return _env_base("LINKFOX_AGENT_USER_API_URL", "https://agent-api.linkfox.com") ``` ```python def _gateway(method: str, path: str, body: dict | None = None) -> dict: """网关 HTTP。401/402/403 明确抛错,5xx 重试 3 次。""" url = f"{_agent_base()}{path}" body_bytes = json.dumps(body or {}).encode() if method == "POST" else None last_exc: Exception = RuntimeError("未知错误") for attempt in range(3): if attempt: ...[truncated 2722 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/collection_pipeline/utils.py:313
Finding

Pipeline job and state files can select arbitrary local Python scripts for execution

Content
View full analysis
dict[str, str]: skill_root = os.path.abspath(skill_root) skills_root = resolve_skills_root(skill_root=skill_root) return { "skill_root": skill_root, "textgen_script": os.path.join(skills_root, "linkfox-aigc-textgen", "scripts", "aigc_textgen.py"), "imagegen_script": os.path.join(skills_root, "linkfox-aigc-imagegen", "scripts", "aigc_imagegen.py"), "brand_gene_save_script": os.path.join( skills_root, "linkfox-aigc-imagegen-brand-gene-extract", "scripts", "save_brand_gene.py" ), "run_one_task_script": os.path.join(skill_root, "scripts", "run_one_task.py"), } def apply_script_paths(job: dict, scripts: dict[str, str]) -> None: """写入下游脚本绝对路径;job 中已有且文件存在则保留,否则用自动解析结果。""" for script_key in ( "textgen_script", "imagegen_script", "brand_gene_save_script", "run_one_task_script", ): resolved = scripts[script_key] existing = job.get(script_key) if existing and os.path.isfile(os.path.abspath(str(existing))): job[script_key] = os.path.abspath(str(existing)) else: job[script_key] = resolved ``` The selected path is persisted in pipeline state: ```python state = { "variant": cfg["variant"], "scene": scene, "imageUrls": image_urls, "image_urls_file": urls_path, "provider": provider, "resolution": job.get("resolution") or "2K ...[truncated 4242 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
skills/linkfox-aigc-imagegen/scripts/onboarding.py:162
Finding

Onboarding recommends unpinned runtime installation of third-party dependencies

Content
View full analysis
dict: try: import qrcode except ImportError: err = "缺少 qrcode 依赖,请运行: pip install qrcode pillow" print(f"{TAG} render_qr: {err}", file=sys.stderr) return {"png_path": None, "ascii_qr": None, "error": err} ``` ```python def _require_requests() -> None: if requests is None: raise RuntimeError("缺少 requests 依赖,请运行: pip install requests") ``` ### Technical Analysis The onboarding flow directs users to install mutable package names without: - Exact versions - Cryptographic hashes - A lockfile - A reviewed package index - An isolated environment - Reproducible build controls Package names are not themselves shown to be malicious. The risk arises because unconstrained `pip install` resolves whatever versions and distributions are available from the user’s configured package index at installation time. A compromised upstream release, malicious mirror, or altered index configuration can therefore introduce executable code into the Agent environment. Python packages may execute code during build and installation, and the imported modules execute with the same privileges as the onboarding process. ### Attack Path 1. The runtime lacks `requests`, `qrcode`, or `pillow`. 2. Onboarding displays the recommended unpinned `pip install` command. 3. The user executes the command in the Agent’s Python environment. 4. Pip resolves packages from the currently configured index without hash verification. 5. A compromised package release, index, mirror, or dependency is downloaded and installed. 6. Mali ...[truncated 545 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (165)

Natural-Language Policy Violations

Critical
Category
Not specified by scanner
Confidence
100% confidence
Finding

The instruction explicitly sets a default race and says Black people must not appear unless specially requested. This is direct discriminatory behavior involving protected characteristics, and in an image-generation skill it can operationalize biased exclusion at scale, creating severe legal, policy, reputational, and user-harm consequences.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Critical
Category
Not specified by scanner
Confidence
100% confidence
Finding

The self-check instruction says Black models should not be used unless imageDesc explicitly specifies otherwise. This is direct exclusion of a protected racial group by default, which is discriminatory system behavior rather than incidental model bias, and is especially dangerous because it is operationalized as a validation rule.

Content

No source excerpt is available for this finding.

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

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The POST target URL is derived from environment-controlled base URLs, and this function sends sensitive data including phone numbers, SMS codes, access tokens, refresh tokens, and token-generation requests. If an attacker can influence environment variables, the script can be redirected to an attacker-controlled endpoint, causing credential and token exfiltration.

Content

Scanner excerpt · skills/linkfox-aigc-imagegen-brand-gene-extract/scripts/onboarding.py (reported line 196)May include surrounding context.

python
except RuntimeError as e:
        return {"_error": str(e)}
    try:
        r = requests.post(url, json=body or {}, headers=headers, timeout=timeout)
        return r.json()
    except Exception as e:
        body_text = ""

Tainted flow: 'req' from os.environ.get (line 244, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
94% confidence
Finding

The gateway request uses a URL built from environment-controlled configuration and attaches the API key in the Authorization header. An attacker who can set the gateway base URL can force outbound requests to a malicious server and capture the API key, account metadata, order details, and other privileged responses.

Content

Scanner excerpt · skills/linkfox-aigc-imagegen-brand-gene-extract/scripts/onboarding.py (reported line 246)May include surrounding context.

python
headers["Content-Type"] = "application/json"
        req = Request(url, method=method, data=body_bytes, headers=headers)
        try:
            with urlopen(req, timeout=30) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            status = e.code

Tainted flow: 'req' from os.environ.get (line 296, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The code downloads arbitrary URLs from resultList via download_media(url, ...) and only checks that the scheme is HTTP/HTTPS. Because the upstream API base can be influenced by environment configuration and the returned result URLs are not allowlisted or validated, a compromised/misconfigured service could coerce the skill into making outbound requests to attacker-controlled hosts and storing untrusted content locally, creating SSRF-style network reachability and untrusted file ingestion risks.

Content

Scanner excerpt · skills/linkfox-aigc-imagegen/scripts/aigc_imagegen.py (reported line 202)May include surrounding context.

python
req = _lf_Request(url, headers={"User-Agent": "LinkFox-Skill/2.0"})
    try:
        with _lf_urlopen(req, timeout=timeout) as resp:
            if guessed_ext == "bin":
                ct = resp.headers.get("Content-Type", "")
                if "mp4" in ct:

Tainted flow: 'req' from os.environ.get (line 296, credential/environment) → urllib.request.urlopen (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 · skills/linkfox-aigc-imagegen/scripts/aigc_imagegen.py (reported line 298)May include surrounding context.

python
}
    req = Request(url, data=data, headers=headers, method="POST")
    try:
        with urlopen(req, timeout=30) as response:
            return json.loads(response.read().decode("utf-8"))
    except HTTPError as e:
        body = e.read().decode("utf-8") if e.fp else ""

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

Critical
Category
Data Flow
Confidence
93% confidence
Finding

The POST target is derived from environment-controlled base URLs and is used to send highly sensitive data including phone numbers, SMS codes, access tokens, refresh tokens, and generated API tokens. If an attacker can influence environment variables in the host runtime, they can redirect authentication traffic to an attacker-controlled endpoint and exfiltrate credentials; in a skill context, this is especially dangerous because the file is explicitly handling onboarding and secret material.

Content

Scanner excerpt · skills/linkfox-aigc-imagegen/scripts/onboarding.py (reported line 196)May include surrounding context.

python
except RuntimeError as e:
        return {"_error": str(e)}
    try:
        r = requests.post(url, json=body or {}, headers=headers, timeout=timeout)
        return r.json()
    except Exception as e:
        body_text = ""

Tainted flow: 'req' from os.environ.get (line 244, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
91% confidence
Finding

The gateway request URL is also built from environment-controlled base configuration and then used in urlopen with the bearer API key in the Authorization header. An attacker who can set the environment can redirect package lookup, order creation, and account queries to a malicious server and capture the API key or manipulate billing-related responses.

Content

Scanner excerpt · skills/linkfox-aigc-imagegen/scripts/onboarding.py (reported line 246)May include surrounding context.

python
headers["Content-Type"] = "application/json"
        req = Request(url, method=method, data=body_bytes, headers=headers)
        try:
            with urlopen(req, timeout=30) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            status = e.code

Tainted flow: 'req' from os.environ.get (line 334, credential/environment) → urllib.request.urlopen (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 · skills/linkfox-aigc-textgen/scripts/aigc_textgen.py (reported line 237)May include surrounding context.

python
req = _lf_Request(url, headers={"User-Agent": "LinkFox-Skill/2.0"})
    try:
        with _lf_urlopen(req, timeout=timeout) as resp:
            if guessed_ext == "bin":
                ct = resp.headers.get("Content-Type", "")
                if "mp4" in ct:

Tainted flow: 'req' from os.environ.get (line 334, credential/environment) → urllib.request.urlopen (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 · skills/linkfox-aigc-textgen/scripts/aigc_textgen.py (reported line 336)May include surrounding context.

python
}
    req = Request(url, data=data, headers=headers, method="POST")
    try:
        with urlopen(req, timeout=HTTP_TIMEOUT) as response:
            return json.loads(response.read().decode("utf-8"))
    except HTTPError as e:
        body = e.read().decode("utf-8") if e.fp else ""

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The POST destination is derived from environment-controlled base URLs, and the request can carry sensitive materials including SMS-login tokens, refresh tokens, generated API keys, phone numbers, and authorization headers. If an attacker can influence the environment, they can redirect these requests to an attacker-controlled host and exfiltrate credentials or impersonate the user.

Content

Scanner excerpt · skills/linkfox-aigc-textgen/scripts/onboarding.py (reported line 196)May include surrounding context.

python
except RuntimeError as e:
        return {"_error": str(e)}
    try:
        r = requests.post(url, json=body or {}, headers=headers, timeout=timeout)
        return r.json()
    except Exception as e:
        body_text = ""

Tainted flow: 'req' from os.environ.get (line 244, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The gateway URL is built from environment-controlled values and then used in urlopen with the API key in the Authorization header. An attacker who can set the environment can redirect billing, package, and account requests to a malicious server and harvest API credentials or manipulate responses used by the CLI.

Content

Scanner excerpt · skills/linkfox-aigc-textgen/scripts/onboarding.py (reported line 246)May include surrounding context.

python
headers["Content-Type"] = "application/json"
        req = Request(url, method=method, data=body_bytes, headers=headers)
        try:
            with urlopen(req, timeout=30) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            status = e.code

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

The workflow explicitly converts local file paths to public URLs via a file-upload skill and instructs agents to expose absolute local result paths in markdown delivery. Undisclosed upload of user-provided local files to external storage and leakage of absolute filesystem paths increase privacy and information-disclosure risk, especially when users may believe the action is limited to local image generation/editing.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The workflow explicitly converts local file paths to public URLs via a file-upload skill and instructs agents to expose absolute local result paths in markdown delivery. Undisclosed upload of user-provided local files to external storage and leakage of absolute filesystem paths increase privacy and information-disclosure risk, especially when users may believe the action is limited to local image generation/editing.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The workflow explicitly converts local file paths to public URLs via a file-upload skill and instructs agents to expose absolute local result paths in markdown delivery. Undisclosed upload of user-provided local files to external storage and leakage of absolute filesystem paths increase privacy and information-disclosure risk, especially when users may believe the action is limited to local image generation/editing.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The workflow explicitly converts local file paths to public URLs via a file-upload skill and instructs agents to expose absolute local result paths in markdown delivery. Undisclosed upload of user-provided local files to external storage and leakage of absolute filesystem paths increase privacy and information-disclosure risk, especially when users may believe the action is limited to local image generation/editing.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The workflow explicitly converts local file paths to public URLs via a file-upload skill and instructs agents to expose absolute local result paths in markdown delivery. Undisclosed upload of user-provided local files to external storage and leakage of absolute filesystem paths increase privacy and information-disclosure risk, especially when users may believe the action is limited to local image generation/editing.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The workflow explicitly converts local file paths to public URLs via a file-upload skill and instructs agents to expose absolute local result paths in markdown delivery. Undisclosed upload of user-provided local files to external storage and leakage of absolute filesystem paths increase privacy and information-disclosure risk, especially when users may believe the action is limited to local image generation/editing.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The workflow explicitly converts local file paths to public URLs via a file-upload skill and instructs agents to expose absolute local result paths in markdown delivery. Undisclosed upload of user-provided local files to external storage and leakage of absolute filesystem paths increase privacy and information-disclosure risk, especially when users may believe the action is limited to local image generation/editing.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The workflow explicitly converts local file paths to public URLs via a file-upload skill and instructs agents to expose absolute local result paths in markdown delivery. Undisclosed upload of user-provided local files to external storage and leakage of absolute filesystem paths increase privacy and information-disclosure risk, especially when users may believe the action is limited to local image generation/editing.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The workflow explicitly converts local file paths to public URLs via a file-upload skill and instructs agents to expose absolute local result paths in markdown delivery. Undisclosed upload of user-provided local files to external storage and leakage of absolute filesystem paths increase privacy and information-disclosure risk, especially when users may believe the action is limited to local image generation/editing.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The workflow explicitly converts local file paths to public URLs via a file-upload skill and instructs agents to expose absolute local result paths in markdown delivery. Undisclosed upload of user-provided local files to external storage and leakage of absolute filesystem paths increase privacy and information-disclosure risk, especially when users may believe the action is limited to local image generation/editing.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The workflow explicitly converts local file paths to public URLs via a file-upload skill and instructs agents to expose absolute local result paths in markdown delivery. Undisclosed upload of user-provided local files to external storage and leakage of absolute filesystem paths increase privacy and information-disclosure risk, especially when users may believe the action is limited to local image generation/editing.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The workflow explicitly converts local file paths to public URLs via a file-upload skill and instructs agents to expose absolute local result paths in markdown delivery. Undisclosed upload of user-provided local files to external storage and leakage of absolute filesystem paths increase privacy and information-disclosure risk, especially when users may believe the action is limited to local image generation/editing.

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

md
| 要多张 / 多类型 / 套图(如"做一套图""出5张图") | **套图编排** | Read `references/runtime/00-index.md` → 按步 Read `01-plan` / `02-confirm` → 调 `scripts/run_collection_pipeline.py` *