Back to skill

Security audit

AIGC文本生成

Security checks for vulnerabilities and agentic risk

Overview

This text-generation skill is not clearly malicious, but it needs Review because it also handles phone login, API-key issuance, payment orders, and credential-bearing requests to environment-configurable endpoints.

Install only if you are comfortable using LinkFox as a remote service for prompts, media URLs, account setup, and billing support. Keep endpoint override environment variables unset unless you fully control the destination, prefer a secret manager over shell-profile API keys, avoid submitting sensitive prompts or personal data, and confirm plan, price, and payment method before any order QR is generated.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/aigc_textgen.py:94
Finding

Configurable generation gateway can exfiltrate API credentials and submitted content

Content
View full analysis

Vulnerability Details

File Location: scripts/aigc_textgen.py:94-96, scripts/aigc_textgen.py:316-339
Vulnerability Type: Unvalidated credential-bearing endpoint override
Risk Level: High

Vulnerable Code

python
def get_api_base():
    """Gateway base address: LINKFOX_TOOL_GATEWAY takes priority; otherwise use production."""
    return (_lf_os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com").rstrip("/")
python
def _post(url, params):
    api_key = get_api_key()
    data = json.dumps(params, ensure_ascii=False).encode("utf-8")
    headers = {
        "Authorization": api_key,
        "Content-Type": "application/json",
        "User-Agent": "LinkFox-Skill/2.0",
        "SESSION_ID": os.environ.get("SESSION_ID", ""),
        "MESSAGE_ID": os.environ.get("MESSAGE_ID", ""),
        "MODE_ID": os.environ.get("MODE_ID", ""),
        "APP_NAME": os.environ.get("APP_NAME", ""),
    }
    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 ""
        try:
            return json.loads(body) if body else {"error": f"HTTP {e.code}: {e.reason}"}
        except Exception:
            return {"error": f"HTTP {e.code}: {e.reason}", "details": body}
    except URLError as e:
        return {"error": f"Connection failed: {e.reason}"}

Technical Analysis

The generation gateway is taken directly from LINKFOX_TOOL_GATEWAY without validating its scheme or hostname. Requests made to that endpoint contain the LinkFox API key in the Authorization header, the complete generation request in the body, and ambient session metadata.

The request body can contain private prompts, user-provided media URLs, model settings, and me ...[truncated 1374 chars]

Remediation
View remediation

Remediation Suggestions

  1. Require https and validate the resolved hostname against an explicit allowlist such as tool-gateway.linkfox.com.
  2. Reject URLs containing user information, unexpected ports, fragments, or non-HTTPS schemes.
  3. Resolve and validate the final destination before attaching authorization headers.
  4. Do not send credentials to a redirected or otherwise changed origin.
  5. If custom endpoints are required for development, place them behind an explicit development-only option and use separate test credentials.
  6. Fail closed when endpoint validation fails and provide a diagnostic that does not reveal the API key.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:69
Finding

Onboarding endpoint overrides can disclose phone numbers, verification codes, and account tokens

Content
View full analysis

Vulnerability Details

File Location: scripts/onboarding.py:69-81, scripts/onboarding.py:379-454
Vulnerability Type: Unvalidated authentication endpoint override
Risk Level: High

Vulnerable Code

python
def _agent_base() -> 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 _login_v3(phone: str, code: str, channel: str) -> dict:
    resp = _login_post("/user/v3/web/login", {
        "type": "sms", "method": "login", "systemId": "LinkFoxAgent",
        "data": {"areaCode": "+86", "authPhone": phone, "authCode": code,
                 "sourceChannel": channel or "skill"},
    })
    if "_error" in resp:
        return {"error": f"login: {resp.get('_body') or resp['_error']}"}
    if not (resp.get("success") or resp.get("code") == "OK"):
        return {"error": f"login: {resp.get('message') or json.dumps(resp, ensure_ascii=False)}"}
    data = resp.get("data") or {}
    access_token, user_id = data.get("accessToken"), data.get("userId")
    if not access_token or not user_id:
        return {"error": f"login: response lacks accessToken/userId: {json.dumps(resp, ensure_ascii=False)}"}
    return {
        "access_token": access_token,
        "refresh_token": data.get("refreshToken", "") or "",
        "user_id": str(user_id),
        "nick_name": data.get("userName", ""),
        "is_new_user": bool(data.get("newUser") or data.get("isFirstRegister")),
    }
python
def _fetch_user_info_v3(access_token: str, user_id: str) -> dict:
    resp = _http_post(f"{_login_base()}/linkFoxApp/api/userCenter/userInfo", {},
                      _headers("agent-linkfox-web", "ag
...[truncated 2706 chars]
Remediation
View remediation

Remediation Suggestions

  1. Allow authentication traffic only to a fixed list of official HTTPS LinkFox hosts.
  2. Validate scheme, normalized hostname, and port before constructing any request.
  3. Refuse to attach access or refresh tokens when the destination origin differs from the expected LinkFox origin.
  4. Disable automatic cross-origin redirects for credential-bearing requests.
  5. Remove production support for arbitrary login endpoint overrides. If testing support is necessary, require an explicit development mode and isolated test credentials.
  6. Avoid including full upstream responses in error messages because they may contain tokens or personal data.
  7. Add tests confirming that HTTP, malformed URLs, lookalike domains, user-information URLs, and unapproved ports are rejected.

other

Note
Location
scripts/aigc_textgen.py:320
Finding

Generation requests transmit undocumented ambient session identifiers

Content
View full analysis

Vulnerability Details

File Location: scripts/aigc_textgen.py:320-328
Vulnerability Type: Excessive telemetry and privacy exposure
Risk Level: Low

Vulnerable Code

python
headers = {
    "Authorization": api_key,
    "Content-Type": "application/json",
    "User-Agent": "LinkFox-Skill/2.0",
    "SESSION_ID": os.environ.get("SESSION_ID", ""),
    "MESSAGE_ID": os.environ.get("MESSAGE_ID", ""),
    "MODE_ID": os.environ.get("MODE_ID", ""),
    "APP_NAME": os.environ.get("APP_NAME", ""),
}

Technical Analysis

Every generation and polling request automatically reads and transmits four ambient environment values: SESSION_ID, MESSAGE_ID, MODE_ID, and APP_NAME. The documented API contract requires the authorization credential and JSON generation parameters but does not document these additional headers or explain why they are necessary.

These values may permit correlation between messages, sessions, host applications, and operational modes. Automatically collecting them exceeds the minimum data described as necessary for text generation unless the service can establish a concrete operational requirement.

Attack Path

  1. The execution environment defines one or more session, message, mode, or application identifiers.
  2. A user invokes text generation.
  3. _post() reads the identifiers without a separate user choice.
  4. The values accompany both task-creation and polling requests.
  5. The receiving service can correlate the generation request with broader agent or application activity.

Impact Assessment

This issue does not directly grant system privileges or code execution. Its impact is privacy-related: it exposes additional contextual identifiers and allows avoidable cross-request or cross-session correlation. If the gateway is redirected as described in the first vulnerability, the same metadata is also exposed to the substituted endpoint.

Remediation
View remediation

Remediation Suggestions

  1. Remove all nonessential ambient metadata headers.
  2. Document each required metadata field, its purpose, retention period, and recipient.
  3. Transmit only identifiers required for the current request and avoid stable cross-session identifiers.
  4. Provide an opt-in configuration for optional diagnostics or telemetry.
  5. Do not attach these values when the destination has not passed strict origin validation.

T09 · Insecure Skill Coding Practices

Warning
Location
references/onboarding.md:12
Finding

Onboarding guidance exposes long-lived API keys through stdout and plaintext shell profiles

Content
View full analysis

Vulnerability Details

File Location: references/onboarding.md:12-16, scripts/onboarding.py:500-507
Vulnerability Type: Plaintext sensitive credential handling
Risk Level: Medium

Vulnerable Code

markdown
- Windows PowerShell (persistent): `setx LINKFOX_AGENT_API_KEY "<key>"`
- macOS zsh: `echo 'export LINKFOX_AGENT_API_KEY="<key>"' >> ~/.zshrc && source ~/.zshrc`
- Linux bash: `echo 'export LINKFOX_AGENT_API_KEY="<key>"' >> ~/.bashrc && source ~/.bashrc`
python
def _cmd_login(args) -> int:
    r = login_and_get_key(args.phone.strip(), args.code.strip(), args.channel)
    _emit(r)
    if "api_key" in r:
        print(f"{TAG} API key successfully obtained (source: {r['source']})", file=sys.stderr)
        return 0
    return 1

The emitted object includes the complete key:

python
return {
    "api_key": tok["api_key"], "phone": masked,
    "group_id": info["group_id"], "member_id": info["member_id"],
    "source": tok["source"], "nick_name": lg.get("nick_name", ""),
    "team_name": info.get("team_name", ""),
    "is_new_user": lg.get("is_new_user", False),
}

Technical Analysis

The login command serializes the complete API key to standard output. In an agent-driven environment, stdout may be captured in execution logs, transcripts, observability systems, or parent-process buffers.

The onboarding documentation then recommends persisting the key directly in .zshrc, .bashrc, or the Windows user environment. Shell profiles are plaintext files and are commonly included in backups, support archives, dotfile repositories, and diagnostic collections. They may also be readable by unintended local processes if permissions are weak.

Persisting a credential is needed for subsequent authenticated calls, but exposing it in general-purpose output and shell startup files is not the safest or least-exposing storage mechanism.

Attack Pa

...[truncated 888 chars]

Remediation
View remediation

Remediation Suggestions

  1. Store API keys through the operating system credential manager or a dedicated secret-management facility.
  2. If file-based storage is unavoidable, use a separate configuration file with owner-only permissions rather than a general shell profile.
  3. Avoid printing the complete key to stdout. Write it directly to the selected secure store and return only a masked fingerprint.
  4. Ensure errors and diagnostics never serialize full authentication responses.
  5. Document key rotation and revocation procedures.
  6. Warn users not to commit profile or configuration files containing credentials to source control.
  7. Recommend short-lived, narrowly scoped credentials where supported.
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
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (22)

Tainted flow: 'req' from os.environ.get (line 335, 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 · 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 335, 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 · scripts/aigc_textgen.py (reported line 337)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
92% confidence
Finding

The script builds request destinations from environment-controlled base URLs and then sends sensitive data such as phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys to those endpoints. If an attacker can influence environment variables, they can redirect these requests to attacker-controlled servers and exfiltrate credentials and payment-related data.

Content

Scanner excerpt · 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
92% confidence
Finding

The urllib gateway path also uses environment-derived base URLs and attaches the user's API key in the Authorization header. An attacker who can set LINKFOX_AGENT_API_URL or related variables can redirect authenticated requests, capturing API credentials and influencing account, package, and order operations.

Content

Scanner excerpt · 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
99% confidence
Finding

The static finding indicates the skill's actual behavior extends far beyond text generation into authentication, API key handling, account access, plan listing, payment order creation, QR rendering, and order-status queries. If accurate, this is a serious scope mismatch: users and supervising agents may invoke a seemingly harmless writing skill while unintentionally triggering account, billing, or credential-related actions against remote services.

Content

No source excerpt is available for this finding.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · references/onboarding.md (reported line 14)May include surrounding context.

md
示 JSON 里的 phone/agreements
   - 收到验证码后:`python scripts/onboarding.py login <phone> <code>`
   - 拿到 `api_key` 后把下面三平台配置转发给用户,提示重启会话生效:
     - Windows PowerShell(永久):`setx LINKFOX_AGENT_API_KEY "<key>"`
     - macOS zsh:`echo 'export LINKFOX_AGENT_API_KEY="<key>"' >> ~/.zshrc && source ~/.zshrc`
     - Linux bash:`echo 'export LINKFOX_AGENT_API_KEY="<key>"' >> ~/.bashrc && source ~/.bashrc`
     - 变量名 `LINKFOX_AGENT_API_KEY`(主推)或 `LINKFOXAGENT_API_KEY`(老规范)任一即可

**billing 场景**:`errcode=402` 或消息含 `算力/余额/quota/insufficient/充值/套餐到期`。
- `python scripts/onboarding.py list-plans` → 有 AskUserQuestion 就弹菜单,否则输出编号清单让用户选
- 校验 `plan_id` ∈ 清单、支付方式 ∈ 该套餐 `available_methods`(通常 `wechat/alipay`)
- `python scripts/onboarding.py order <plan_id> <method>` → 展示优先级 PNG

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This file implements SMS login, token exchange, API-key generation, package listing, order creation, and payment QR handling, which are unrelated to a text-generation skill's declared purpose. Such hidden account onboarding and monetization flows materially expand the attack surface and can trick users into disclosing credentials or authorizing charges under false pretenses.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

Embedding subscription purchase and payment QR generation inside a text-generation skill is unjustified by the stated functionality and creates a path for unexpected financial transactions. In this context, the mismatch makes the behavior more dangerous because users invoking writing assistance would not reasonably expect billing workflows to be triggered.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code retrieves or generates persistent API tokens for the user after SMS login, which is highly sensitive capability escalation unrelated to ordinary text generation. In this skill context, hidden token issuance is especially dangerous because it can grant long-lived access beyond the user's immediate session.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill exposes capabilities implying environment access, file writing, and network use, but it does not declare any tool scope or permission boundaries. In an agent ecosystem, this weakens least-privilege controls and makes it harder for orchestrators or reviewers to understand and constrain what the skill may do, increasing the blast radius if misused or chained unexpectedly.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger phrases are very broad, including common requests like '帮我写一段', 'AI写作', and '图片识别', which can cause the skill to activate in many ordinary conversations. Over-broad triggering increases the chance of unintended remote data submission, accidental tool execution, and incorrect routing away from safer or more specific skills.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill processes prompts and image/video URLs through remote AI and HTTP services, but the description does not warn users that their content will be transmitted off-platform. This creates a privacy and consent risk, especially because prompts, images, and videos may contain sensitive business or personal data.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · references/api.md (reported line 111)May include surrounding context.

| 10009 | 任务不存在 | 检查 taskId 是否正确 | | 其他 | 业务异常 | 参考 errmsg 字段 |

curl 示例

bash
# 1. 创建任务

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documentation exposes a separate feedback submission endpoint that is unrelated to the core text-generation API and encourages sending free-form content externally. Because the feedback payload can include user statements and observations about interactions, it creates an additional data egress path that may be invoked without clear user awareness or purpose limitation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The feedback API section instructs clients to send a content field describing what the user said and what happened, but it does not warn that this may transmit user-provided text to a third-party service. That omission creates a privacy and data-handling risk, especially if operators include sensitive prompts, outputs, or personal data in feedback submissions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The onboarding flow instructs the operator to collect a user's phone number and pass it to a registration script, but it provides no consent, retention, masking, or privacy-handling guidance. Because phone numbers are personal data and the flow also handles verification codes, this creates avoidable privacy and account-security risk if operators collect, display, log, or forward the data insecurely.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document tells users to persist an API key in shell startup files or environment settings without warning that this makes the secret long-lived and potentially readable by other local processes, backups, shell history, screenshots, or support logs. While common operationally, instructing permanent storage of credentials without safer alternatives or cautions increases the chance of credential leakage and account misuse.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This Python file contains the main module docstring and operational guidance entirely in Chinese, which imposes a specific language on users and downstream agents. Under the policy, forcing a language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The CLI description, help text, log messages, phone validation, and API parameters are all fixed to a Chinese-language and mainland China context, including +86 and '11 位国内手机号'. This enforces a specific language/locale behavior without offering the user a choice or documenting it as an explicit opt-in in the file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script writes session directories and payment QR images to disk in predictable user-accessible locations without explicit notice or retention controls. These artifacts can expose payment URLs, order metadata, or session correlation data to other local users or later processes on shared systems.

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/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 = ""

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The manifest describes an AI text-generation skill with image/video understanding, which clearly justifies calling a backend model API. However, this code also pulls authentication and multiple execution-context values from environment variables (API key, SESSION_ID, MESSAGE_ID, MODE_ID, APP_NAME) and forwards them in outbound requests, a capability not described in the skill purpose itself.

Content

No source excerpt is available for this finding.