Back to skill

Security audit

图可丽视觉api

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Tukeli image-processing skill, but it should go to Review because it sends images and an API key to a paid external service with weak or inaccurate safeguards.

Install only if you are comfortable sending selected images, image URLs, prompts, and optional facial landmark data to Tukeli's servers and paying for API usage. Do not rely on the documented TUKELI_MAX_IMAGES_PER_DAY limit unless it is implemented or enforced provider-side, and prefer running it in an isolated environment with a scoped API key and reviewed dependency pinning.

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/tukeli.py:93
Finding
API credential may be disclosed through cross-origin HTTP redirects<![CDATA[ ## Vulnerability Details **File Location**: `scripts/tukeli.py:93-99`, `scripts/tukeli.py:124`, and `scripts/tukeli.py:145-147` **Vulnerability Type**: Credential exposure through unrestricted redirects **Risk Level**: Medium ### Vulnerable Code ```python resp = requests.post( url, params=url_params, files=files, headers=headers, timeout=timeout, ) ``` ```python resp = requests.get(url, params=all_params, headers=headers, timeout=timeout) ``` ```python if method == "POST": resp = requests.post(url, json=body, headers=headers, timeout=timeout) else: resp = requests.get(url, params=body, headers=headers, timeout=timeout) ``` The transmitted headers include the user's credential: ```python headers = { "APIKEY": api_key, "User-Agent": USER_AGENT, } ``` ### Technical Analysis Python Requests follows HTTP redirects by default for these calls. The credential is carried in the custom `APIKEY` header rather than the standard `Authorization` header. Redirect protections that specifically remove `Authorization` during a cross-origin redirect do not necessarily protect arbitrary credential headers. The initial destination is hardcoded to `https://picupapi.tukeli.net`, which limits ordinary endpoint manipulation. However, if that service, its DNS resolution, its TLS termination infrastructure, or its redirect behavior is compromised or misconfigured, it could return a redirect to another origin. The client does not reject redirects or verify that every redirect destination remains on the expected HTTPS host. Sending images and the API key to Tukeli is necessary for the declared remote image-processing functionality. Allowing the credential and image request to follow an unrestricted redirect exceeds the minimum network privilege required. ### Attack Path 1. An attacker compromises or misconfigures the Tukeli API endpoint, reverse proxy, or redirect behavior. 2. A user invokes image matting, face enhancement, AI backgr ...[truncated 974 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Disable automatic redirects on all authenticated requests: ```python resp = requests.post( url, params=url_params, files=files, headers=headers, timeout=timeout, allow_redirects=False, ) ``` Apply the same control to every authenticated `requests.get` and `requests.post` call. If redirects are required: 1. Handle each redirect manually. 2. Parse and normalize the destination URL. 3. Require the scheme to be exactly `https`. 4. Require the normalized hostname to be exactly `picupapi.tukeli.net`. 5. Reject URLs containing unexpected ports, embedded credentials, or ambiguous host syntax. 6. Set a small maximum redirect count. 7. Reconstruct sensitive headers only after validating the next destination. 8. Consider using a dedicated `requests.Session` with a redirect policy that strips `APIKEY` whenever the origin changes. ]]>

T08 · Insecure Dependencies

Note
Location
scripts/requirements.txt:4
Finding
Dependencies are installed without reproducible version and integrity controls<![CDATA[ ## Vulnerability Details **File Location**: `scripts/requirements.txt:4` **Vulnerability Type**: Unbounded and unhashed third-party dependency **Risk Level**: Low ### Vulnerable Code ```text requests>=2.28.0 ``` The documented installation command is: ```bash pip install -r scripts/requirements.txt ``` ### Technical Analysis The lower-bound-only requirement permits installation of any future Requests release accepted by the package resolver. Transitive dependencies are also not locked, and no package hashes are provided. This creates non-reproducible installations and expands the supply-chain trust boundary beyond the dependency versions reviewed with the Skill. A compromised, malicious, or unexpectedly incompatible future release could change security-relevant HTTP behavior or execute package installation code in the user's Python environment. No evidence was found that the current `requests` package name is a typosquat or intentionally malicious. The issue is the absence of version locking and artifact integrity verification, not a confirmed compromise of the dependency. ### Attack Path 1. A future permitted Requests release or one of its resolved dependencies is compromised, malicious, or replaced at an untrusted package source. 2. A user runs the documented `pip install -r scripts/requirements.txt` command. 3. The resolver selects the affected release because no exact version, lock file, or hash restricts it. 4. Malicious installation or runtime code executes with the privileges of the user running `pip`. 5. The affected dependency may access environment variables, local files available to the process, API credentials, or image data processed by the Skill. ### Impact Assessment The potential privilege level is that of the user or environment performing package installation and subsequently running the Skill. Depending on the compromised package behavior, impact could include credential theft, local data disclosure, arbitrary code execut ...[truncated 245 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Use a reviewed, reproducible dependency set: ```text requests==<reviewed-version> --hash=sha256:<verified-hash> ``` Additionally: 1. Lock all transitive dependencies using a trusted lock-generation workflow. 2. Install with `pip install --require-hashes -r requirements.txt`. 3. Use only trusted package indexes configured over TLS. 4. Review dependency updates before regenerating the lock file. 5. Run automated vulnerability and provenance checks on locked artifacts. 6. Prefer installation in an isolated virtual environment with minimum filesystem and credential access. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
references/setup-guide.md:119
Finding
Documented daily paid-API usage limit is not implemented<![CDATA[ ## Vulnerability Details **File Location**: `references/setup-guide.md:119` **Vulnerability Type**: Missing resource-consumption control and inaccurate security documentation **Risk Level**: Low ### Vulnerable Documentation The setup guide states that daily processing can be limited through: ```text TUKELI_MAX_IMAGES_PER_DAY ``` It also represents the default daily limit as 100. However, the audited implementation contains no corresponding read or enforcement of this environment variable in `scripts/config.py` or `scripts/tukeli.py`. ### Technical Analysis The Skill invokes paid API operations and includes automatic retries. Operators may rely on the documented environment variable as a safeguard against excessive API usage and credit consumption, but the implementation never checks it. This is a fail-open resource-control condition: all valid invocations proceed regardless of the configured value. Although it does not create local privilege escalation, it undermines the represented cost-control boundary and can allow automation, accidental loops, or abusive invocation patterns to consume more paid operations than intended. ### Attack Path 1. An operator configures `TUKELI_MAX_IMAGES_PER_DAY`, believing the documented daily cap is enforced. 2. A user, automation loop, or repeated task invokes the Skill more times than the configured limit. 3. The executable never reads the variable and never maintains a daily request counter. 4. Every invocation continues to reach the paid Tukeli API. 5. Requests, including retried operations, may consume credits beyond the operator's intended limit. ### Impact Assessment The impact is unexpected financial and resource consumption within the Tukeli API account. An attacker who can invoke the Skill could repeatedly trigger paid operations up to any external service-side limits. The issue does not grant additional local permissions, arbitrary code execution, or access to unrelated accounts. Its scope is paid ...[truncated 63 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Either implement the documented control or remove the unsupported claim. For implementation: 1. Parse `TUKELI_MAX_IMAGES_PER_DAY` as a positive integer and reject invalid values. 2. Maintain a persistent counter keyed by calendar date and API account. 3. Update the counter atomically with file locking or a transactional local store. 4. Check the limit before submitting a paid operation. 5. Define whether failed requests and retries count toward the limit. 6. Prevent concurrent processes from bypassing the counter. 7. Restrict permissions on the counter storage so untrusted users cannot reset it. 8. Return a clear error when the daily limit is reached. 9. Document that a local limit is advisory unless combined with a provider-side quota or billing cap. Where possible, also configure a server-side Tukeli quota because client-side counters can be bypassed by direct API use or deletion of local state. ]]>
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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (25)

Credential Access

High
Category
Privilege Escalation
Content
def _parse_env_file(env_path: Path) -> dict[str, str]:
    """解析 .env 文件,返回 key=value 字典。"""
    result: dict[str, str] = {}
    if not env_path.exists():
        return result
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def _parse_env_file(env_path: Path) -> dict[str, str]:
    """解析 .env 文件,返回 key=value 字典。"""
    result: dict[str, str] = {}
    if not env_path.exists():
        return result
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def _parse_env_file(env_path: Path) -> dict[str, str]:
    """解析 .env 文件,返回 key=value 字典。"""
    result: dict[str, str] = {}
    if not env_path.exists():
        return result
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
key = os.environ.get("TUKELI_API_KEY")
    if key:
        return key
    env_data = _parse_env_file(ROOT_DIR / ".env")
    return env_data.get("TUKELI_API_KEY")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill performs sensitive actions implied by its documentation and referenced scripts—reading local files, writing outputs/metadata, accessing environment variables for API keys, and making network requests—yet it does not declare any explicit tool scope or allowed-tools boundaries. This weakens least-privilege controls and makes it easier for an agent runtime to grant broader capabilities than users expect, increasing the blast radius if the skill is misused or compromised.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill describes uploading local images or submitting image URLs to a third-party cloud API, but it does not clearly warn users that their content will leave the local environment and be processed by an external service. This creates a privacy and data-handling risk, especially for personal photos, faces, IDs, or other sensitive imagery, because users may invoke the skill without informed consent about external transmission.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The documentation describes uploading image files and submitting image URLs to a third-party API but does not clearly warn users that their images will be transmitted off-platform to an external service. This creates privacy and compliance risk, especially if users send sensitive, proprietary, or personal images under the assumption processing is local or first-party.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The faceAnalysis option returns facial landmarks and face bounding data, which may constitute biometric or sensitive personal data in many jurisdictions. Documenting this feature without a clear warning can lead integrators to unknowingly collect, transmit, or store regulated facial data, increasing privacy, legal, and misuse risk.

External Transmission

Medium
Category
Data Exfiltration
Content
```python
import requests

response = requests.post(
    'https://picupapi.tukeli.net/api/v1/matting?mattingType=6',
    files={'file': open('/path/to/file.jpg', 'rb')},
    headers={'APIKEY': 'INSERT_YOUR_API_KEY_HERE'},
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```python
import requests

response = requests.post(
    'https://picupapi.tukeli.net/api/v1/matting?mattingType=6',
    files={'file': open('/path/to/file.jpg', 'rb')},
    headers={'APIKEY': 'INSERT_YOUR_API_KEY_HERE'},
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```python
import requests

response = requests.post(
    'https://picupapi.tukeli.net/api/v1/matting?mattingType=6',
    files={'file': open('/path/to/file.jpg', 'rb')},
    headers={'APIKEY': 'INSERT_YOUR_API_KEY_HERE'},
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
import requests

# 提交任务
response = requests.post(
    'https://picupapi.tukeli.net/api/v1/paintAsync',
    json={
        'imgUrl': 'https://example.com/transparent.png',
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The guide tells users to submit local files or image URLs to an external API endpoint but does not clearly disclose that image content will leave the local environment and be processed by a third party. This creates a real privacy and data-governance risk, especially if users upload sensitive photos, biometric data, or proprietary images without informed consent.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
This file presents its descriptive documentation entirely in Chinese, and the user-facing exception messages are also hard-coded in Chinese. Under the policy, forcing a specific language without user opt-in or clear justification is a natural-language policy violation.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill uploads local image files or sends image URLs to a third-party API, but the runtime flow does not provide a prominent consent/privacy warning before transmission. Users may unknowingly send sensitive personal images or internal URLs to an external service, creating privacy and data-handling risk.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The AI background feature transmits image content and free-form text prompts to a third-party endpoint without a clear in-band warning or consent mechanism. Because prompts and images may contain personal, confidential, or regulated data, silent transmission increases privacy and compliance risk.

External Transmission

Medium
Category
Data Exfiltration
Content
}

    if method == "POST":
        resp = requests.post(url, json=body, headers=headers, timeout=timeout)
    else:
        resp = requests.get(url, params=body, headers=headers, timeout=timeout)
Confidence
84% confidence
Finding
This code sends user-supplied images/text to an external API over the network, which is expected for the skill but still security-relevant because sensitive data may leave the local environment. In the skill context, the danger is not hidden malware behavior but undisclosed third-party data transfer and possible exposure of personal or confidential content.

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

Medium
Category
Data Flow
Content
}

    if method == "POST":
        resp = requests.post(url, json=body, headers=headers, timeout=timeout)
    else:
        resp = requests.get(url, params=body, headers=headers, timeout=timeout)
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: 'body' from requests.get (line 158, network input) → requests.get (network output)

Medium
Category
Data Flow
Content
if method == "POST":
        resp = requests.post(url, json=body, headers=headers, timeout=timeout)
    else:
        resp = requests.get(url, params=body, headers=headers, timeout=timeout)

    _raise_for_status(resp)
    return resp.json()
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.

Natural-Language Policy Violations

Low
Confidence
83% confidence
Finding
文件中的自然语言说明全部为中文,且未提供多语言选项、英文别名或声明该技能仅面向中文用户。根据语言/区域政策,若技能强制特定语言而无用户选择或合理限定,可能构成自然语言策略问题。

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
A language or locale policy issue can arise when a skill forces a specific language without user opt-in. This file presents all instructions in Chinese and does not indicate that the skill is region-specific or provide an alternative language option.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
This requirements file contains natural-language comments only in Chinese, which may impose a specific language/locale on users without offering a choice or documenting a justified region-specific constraint. The policy for this audit flags language or locale restrictions when they are forced without opt-in.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# 图可丽视觉 API Skill - 依赖
# 安装:pip install -r requirements.txt

requests>=2.28.0
Confidence
93% confidence
Finding
The dependency is specified as `requests>=2.28.0`, which allows installation of a wide range of versions and makes builds non-reproducible. In a skill that calls external visual-processing APIs and may handle image URLs, uploads, credentials, and remote network traffic, leaving `requests` unpinned increases the chance of pulling in a vulnerable or behavior-changing release during deployment.

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
84% confidence
Finding
`requests` has multiple published advisories, and because the manifest does not pin a specific version, there is no way to verify whether the installed package includes fixes. Given this skill's purpose—making outbound HTTP requests to a third-party image API and potentially fetching user-supplied URLs—dependency uncertainty can expose secrets, request metadata, or transport security assumptions if an affected version is resolved.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
文件头文档、CLI 描述和用户输出均固定为中文,没有提供语言切换、用户选择或对中文限定场景的说明。按规则,强制特定语言而无用户 opt-in 可能构成语言/locale 政策问题。

Static analysis

No suspicious patterns detected.