Back to skill

Security audit

Meta Analysis / 医学Meta分析

Security checks for vulnerabilities and agentic risk

Overview

The skill’s cloud-analysis purpose is mostly coherent, but it includes remote-controlled file transfer paths that can read local files or write outside the output folder without clear user control.

Review before installing. Use this only if you trust the configured Coze/LongCat services and are comfortable sending analysis summary data to cloud endpoints. Avoid sensitive workspaces until file uploads require explicit user-selected files, download filenames are contained to the output directory, custom endpoints are allowlisted, and per-file upload/download confirmation is added.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
adapters/coze_client.py:1200
Finding

Remote Tool Cards Can Trigger Unauthorized Upload of Arbitrary Local Files

Content
View full analysis

Vulnerability Details

File Location: adapters/coze_client.py, lines 1200, 1457–1469, and 1634
Vulnerability Type: Remote-controlled arbitrary local file disclosure
Risk Level: High

Vulnerable Code:

python
out["tool_cards"] = _json_or_obj(outer.get("tool_cards")) or []
python
local_files = params.get("_local_files") or []
put_urls = params.get("_put_urls") or {}
refs = []
for item in local_files:
    lp = item if isinstance(item, str) else item.get("path")
    purp = None if isinstance(item, str) else item.get("purpose")
    if not lp:
        continue
    ref = _upload_file(lp, purpose=purp)
    url = put_urls.get(lp) or put_urls.get(os.path.basename(lp))
    if url:
        with open(os.path.abspath(lp), "rb") as f:
            _http_put(url, f.read(), headers={"Content-Type": ref["mime"]})
        ref["put_url"] = url
    refs.append(ref)
python
cards = resp.get("tool_cards") or []
if cards:
    outs = execute_tool_cards(cards, out_dir=out_dir)

Technical Analysis

parse_stage_response() accepts tool_cards from the remote Coze response. run_pipeline() then passes those cards directly to execute_tool_cards() without requiring user confirmation.

For a request_upload card, the remote response can populate:

  • params["_local_files"], which identifies local paths to read.
  • params["_put_urls"], which identifies destinations receiving those files.

The implementation converts each supplied path to an absolute path, reads the complete file, and transmits it using _http_put(). There is no canonical path allowlist, workspace containment check, opaque client-side file identifier, or confirmation tied to the specific file and destination.

Although the Skill discloses that analysis data is sent to Coze, that authorization does not grant the remote service permission to select unrelated files from the local filesystem.

Attack Path

  1. The user starts a workflow through run_pipeline().
  2. The client ...[truncated 1151 chars]
Remediation
View remediation

Remediation Suggestions

  1. Never accept raw local filesystem paths from remote tool cards.
  2. Maintain a client-side registry of files explicitly selected by the user and expose only opaque file IDs to the remote service.
  3. Resolve each selected path canonically and require it to remain inside an explicitly approved workspace or upload directory.
  4. Require file-specific user confirmation showing:
    • Canonical local path
    • File size and type
    • Destination hostname
    • Purpose of the upload
  5. Restrict upload URLs to authenticated HTTPS origins on an explicit allowlist.
  6. Reject redirects to unapproved origins.
  7. Apply file-size and file-type limits before reading data.
  8. Ensure the remote service cannot introduce new local paths during pipeline continuation.
  9. Record a security audit event for every approved upload without logging file contents or credentials.

T09 · Insecure Skill Coding Practices

Error
Location
adapters/coze_client.py:1234
Finding

Remote Attachment Filenames Allow Writes Outside the Selected Output Directory

Content
View full analysis

Vulnerability Details

File Location: adapters/coze_client.py, lines 1234–1240, 1416–1422, and 1623–1624
Vulnerability Type: Path traversal and arbitrary file overwrite
Risk Level: High

Vulnerable Code:

python
atts = outer.get("attachments")
if isinstance(atts, str):
    try:
        atts = json.loads(atts)
    except Exception:
        atts = None
out["attachments"] = atts if isinstance(atts, list) else []
python
raw = _http_get(att["url"])
sha_ok = True
if att.get("sha256"):
    sha_ok = hashlib.sha256(raw).hexdigest() == att["sha256"]
fname = att.get("filename") or os.path.basename(att.get("key") or "download")
path = os.path.join(out_dir, fname)
with open(path, "wb") as f:
    f.write(raw)
results.append({
    "filename": fname,
    "path": path,
    "ok": True,
    "sha256_ok": sha_ok
})
python
if resp.get("attachments"):
    downloaded += download_attachments(resp["attachments"], out_dir)

Technical Analysis

Attachment metadata originates in the remote Coze response. The response contract explicitly identifies filename as the name used for local storage, but download_attachments() joins that value directly to out_dir.

The implementation does not:

  • Reject absolute filenames
  • Remove directory components
  • Reject .. traversal segments
  • Resolve and verify canonical containment beneath out_dir
  • Prevent overwriting existing files
  • Abort the write when the SHA-256 check fails

Consequently, a filename such as ../../target-file can escape the output directory. On platforms where os.path.join() accepts an absolute second component by replacing the prefix, an absolute filename can also disregard out_dir entirely.

The hash check does not prevent exploitation because the remote response controls both the content and expected hash. Moreover, even a detected mismatch is only recorded in sha256_ok; the file is still written and reported with ok: True.

Attack Path

  1. The user runs a cloud ...[truncated 1275 chars]
Remediation
View remediation

Remediation Suggestions

  1. Treat every attachment filename as untrusted.
  2. Reject absolute paths, drive-qualified paths, path separators, NUL bytes, and . or .. path components.
  3. Reduce accepted names to a sanitized basename and generate a safe local filename when necessary.
  4. Resolve both the output directory and destination path canonically, then verify containment:
python
base = os.path.realpath(out_dir)
name = os.path.basename(untrusted_name)
destination = os.path.realpath(os.path.join(base, name))

if os.path.commonpath([base, destination]) != base:
    raise ValueError("Attachment path escapes output directory")
  1. Validate the downloaded content hash before opening the destination file. Delete temporary data and abort on mismatch.
  2. Download into a securely created temporary file inside out_dir, validate it, and atomically rename it afterward.
  3. Avoid silently overwriting existing files; use exclusive creation or require explicit overwrite approval.
  4. Enforce response-schema validation, download-size limits, allowed file types, and approved HTTPS storage origins.
  5. Add regression tests covering:
    • ../ traversal
    • Absolute Unix paths
    • Windows drive and UNC paths
    • Nested directory components
    • Symbolic-link destinations
    • Hash mismatches
    • Existing-file collisions
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (277)

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The batch PDF resolution path also sends authenticated requests to STREAM_ENDPOINT derived from environment input. In this skill context, requests may include DOI lists and audit metadata, so redirecting traffic to an attacker-controlled host could leak sensitive operational data and credentials.

Content

Scanner excerpt · adapters/ctsearch_client.py (reported line 437)May include surrounding context.

python
req = urllib.request.Request(STREAM_ENDPOINT, data=body,
                                     headers=_headers(), method="POST")
        try:
            with urllib.request.urlopen(req, timeout=timeout) as r:
                part = _parse_coze_stream(r, progress)
        except Exception as e:
            progress("[coze] 流式传送失败: %s: %s" % (type(e).__name__, e))

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

Critical
Category
Data Flow
Confidence
91% confidence
Finding

The request destination is taken from an environment-controlled endpoint (CT_SEARCH_ENDPOINT_STREAM) and then used directly in urllib.request.urlopen with an Authorization bearer token attached. If an attacker can influence the runtime environment, they can redirect requests and exfiltrate the token, query contents, and returned data to an attacker-controlled server, creating an SSRF-style outbound trust violation.

Content

Scanner excerpt · adapters/ctsearch_client.py (reported line 527)May include surrounding context.

python
try:
        req = urllib.request.Request(STREAM_ENDPOINT, data=body,
                                     headers=_headers(), method="POST")
        with urllib.request.urlopen(req, timeout=timeout) as r:
            projects = _parse_coze_stream(r, lambda m: None)
        # 注意:_parse_coze_stream 解析失败返回 [](而非 None)——若直接接受,
        # 「解析失败」会伪装成「检索无结果」,上游据此误判重试 → 同参重复出站

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

Critical
Category
Data Flow
Confidence
91% confidence
Finding

The fallback /run request uses ENDPOINT sourced from CT_SEARCH_ENDPOINT without validating the target, while _headers may include a bearer token. An attacker controlling environment configuration could cause sensitive search requests and credentials to be sent to an arbitrary external server.

Content

Scanner excerpt · adapters/ctsearch_client.py (reported line 543)May include surrounding context.

python
try:
        req2 = urllib.request.Request(ENDPOINT, data=body,
                                      headers=_headers(), method="POST")
        with urllib.request.urlopen(req2, timeout=timeout) as r2:
            data = json.loads(r2.read().decode("utf-8"))
        return _parse_run_response(data, source)
    except Exception as e:

Tainted flow: 'req' from os.environ.get (line 88, 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 · adapters/llm_client.py (reported line 93)May include surrounding context.

python
"Authorization": f"Bearer {key}",
    })
    try:
        with urllib.request.urlopen(req, timeout=timeout) as resp:
            data = json.loads(resp.read().decode("utf-8"))
        if raw:
            return data

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

Critical
Category
Data Flow
Confidence
94% confidence
Finding

The code builds an outbound HTTP request from environment- and file-derived endpoint configuration and sends user-provided research topics plus credentials to that endpoint without any allowlist, origin validation, or trust boundary enforcement. In skill/server context this enables SSRF-style redirection and silent exfiltration of sensitive prompts or API keys if an attacker can influence environment variables, models.json, or bundled key-loading behavior.

Content

Scanner excerpt · adapters/topic_translate.py (reported line 236)May include surrounding context.

python
if key:
        headers["Authorization"] = "Bearer " + key
    req = urllib.request.Request(base, data=body, headers=headers, method="POST")
    with urllib.request.urlopen(req, timeout=timeout) as resp:
        j = json.loads(resp.read().decode("utf-8"))
    content = (j.get("choices") or [{}])[0].get("message", {}).get("content") or ""
    return content if raw else _strip_noise(content)

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The document claims that no raw datasets are uploaded, yet the execution contract explicitly sends data to a remote Coze endpoint for analysis. This creates a material transparency and privacy-risk issue: users may provide sensitive study data under a false assumption about what leaves the local environment, which can lead to unauthorized disclosure or regulatory noncompliance.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The README makes contradictory privacy/confidentiality claims: the confidentiality notice says Tier A skills run fully locally, while earlier sections clearly state this skill auto-sends analysis inputs to a cloud endpoint by default. That mismatch can mislead users about data handling and cause them to disclose sensitive research or clinical summary data under false assumptions.

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

md
**Project Files**: `README.md` | `README_zh-CN.md` | `CHANGELOG.md` | `AGENTS.md` | `LICENSE` (MIT © 2025 medstatstar) | `requirements.txt` | `assets/icon.svg`.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 198)May include surrounding context.

md
**Project Files**: `README.md` | `README_zh-CN.md` | `CHANGELOG.md` | `AGENTS.md` | `LICENSE` (MIT © 2025 medstatstar) | `requirements.txt` | `assets/icon.svg`.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module-level documentation asserts the component is fully local and will not trigger outbound auth, but the implementation performs multiple network-backed operations such as cc.run_meta(), ctsearch_client.search_literature(), registry/PROSPERO probes, translation/model calls, DOI/PMID/PDF resolution, and Coze rescue/download paths. This kind of trust-boundary misrepresentation is dangerous because operators may approve or deploy the skill in restricted environments under false assumptions, leading to unintended data egress, policy bypass, or use of external services without informed consent.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The top-level documentation repeatedly states that this module 'only orchestrates + sends/receives locally' and that coze is the 'only computation source'. However, the code includes a full local pairwise meta-analysis engine in b1_pairwise_python, a local R-based network meta-analysis path in b1_nma_r, and local heuristic computation for B2/B3/B4. This is an active contradiction between documented intent and implemented behavior, not merely omitted detail.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file claims there is no retained local computation engine, yet it still contains run_stage_local that executes a local R engine. This inconsistency is dangerous because operators and reviewers may believe all computation is remote and gated, while a hidden or residual local execution path remains available and can bypass architectural, auditing, or authorization assumptions.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code uses importlib to load and execute an arbitrary Python file in order to read a constant, but the docstring incorrectly suggests this avoids executing other code. Any attacker who can modify or replace config/llm_key.py can run arbitrary code with the application's privileges during key loading, turning a secret-loading path into a code-execution path.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file makes strong efficacy and clinical-use claims while explicitly stating the underlying dataset is fictional and not suitable for real clinical decision-making. In a health-related skill, this contradiction can mislead downstream users or systems into treating fabricated evidence as trustworthy medical guidance, creating a material risk of harmful decisions.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The menu at L149 presents '[2] 改检索式' as a user action. But L403-L426 explicitly explains that EDITABLE_KEYS does not include A2.literature_search, making A2's editable payload empty and leaving the revision path unimplemented; the document even says the menu may not deserve this option if it only writes a patch without rerunning.

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 · references/migration-notes-aipoch.md (reported line 90)May include surrounding context.

md
| Egger/Begg at k ≥ 3 | Severely underpowered; produces false reassurance. Corrected to k ≥ 10. |
| Baujat axis labels | Upstream labels `bj$x` as "contribution to overall result" and `bj$y` as "contribution to Q" — **swapped**. Its manual fallback branch also assigns the axes opposite to its primary branch. Corrected in `baujat-plot.md` §3. |
| Egger's test for binary/OR outcomes | Known bias from the logOR–SE correlation. Harbord/Peters substituted in `funnel-plot.md` §3. |
| Upstream boilerplate sections ("Validation Shortcut", "Deterministic Output Rules", "Completion Checklist", "Quick Validation", auto-generated "Key Features") | Template filler, partly inaccurate (e.g. `python scripts/extract_criteria.py --help` as the validation path for a forest-plot skill). No value here. |

## D. Notes for the Maintainer

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file states the AGENTS.md and related published-skill materials are 'English-only,' which imposes a language constraint without user opt-in. Combined with the later default-English and OS-locale auto-switch behavior, this reflects a language policy decision not explicitly driven by user choice.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
93% confidence
Finding

The skill is configured to automatically execute remote analysis as soon as the user describes a request, with no preview-confirmation gate. Because this skill sends analysis inputs to an external endpoint, auto-execution increases the chance of unintended data disclosure, accidental processing of sensitive inputs, and reduced user control over consequential outbound actions.

Content

Scanner excerpt · AGENTS.md (reported line 22)May include surrounding context.

md
- Never hardcode paths.

### 2. Code Execution / 代码执行规范
- **Default: AUTO-EXECUTE**. Once the user describes an analysis request, call the unified front door `adapters/run_analysis.run_analysis(task, data, params, figure)` and return results — no preview-confirm gate. Before the **first outbound call each session**, give a one-time spoken disclosure of what is sent and to which endpoint (ct-base §5), then execute automatically.
- **Execution (coze only)**: `run_analysis` calls coze. On coze failure / unauthorized it returns a structured error (`{status:"error", ...}`) — no local fallback. The successful result carries `_source="coze"`.
  - Successful result shape: `{status, stats, figures[].svg, warnings, notes, _source}`.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

These lines define English as the default and automatically switch to Chinese when the OS locale contains zh/CN. This is a locale-based behavior affecting user-facing prompts, and the policy explicitly says not to force a language or locale without user opt-in.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

At L1967 the entry explicitly claims '无代码改动', but the body documents changes to normative behavior and exposed contract expectations such as new D18/D19 findings, updated CCM calling guidance, and revised implementation status statements. Because this file is itself documentation, asserting 'no code changes' while simultaneously revising what the system is said to do creates intent/documentation divergence for auditors and operators.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Auto-switching language based on OS/locale rather than the user's explicit choice can cause the skill to send, display, or interpret sensitive content in the wrong language context. In a medical-analysis workflow, that increases the risk of user misunderstanding, incorrect consent around outbound processing, and malformed requests when multilingual data or instructions are involved.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
93% confidence
Finding

The changelog explicitly states a shift from preview/confirmation to automatic execution, meaning user descriptions can trigger analysis and outbound processing without a distinct execution confirmation step. In this skill's context, that is risky because it handles medical-analysis inputs and may transmit data to remote services, so accidental execution can expose data or produce consequential outputs without deliberate user intent.

Content

Scanner excerpt · CHANGELOG.md (reported line 3780)May include surrounding context.

md
- **README 结构重排(§13.3)**:对话示例前置、出站披露收敛为「数据与隐私」节;实测记录迁至 ADVANCED。
- **ct-base 注解清理**:对外文档(README/SKILL/AGENTS/interactive_menu)清除 `(ct-base §X)` 引用;内部技术文档(ADVANCED/units 等)保留溯源(§4 文档清理边界)。
- **安全审计披露矛盾修复(SkillSpector §16.0)**:修正 `data:` 字段"no external data transmission"、README"never touches raw datasets"、bug-report"本地保存+邮件作者"等声明与实际不符处。
- **执行模式变更(安全预览 → 自动执行,2026-08-24)**:技能从「默认展示 R 代码、需说『请直接计算』才执行」改为**自动执行**——用户描述需求后技能自动完成分析并返回结果,无需触发词。同步更新 README(中/英)顶部简介、示例注记、FAQ、原「安全预览」节(改为「执行机制」)、出站披露触发时机(改为自动发送 + 每会话首次出站前披露一次);AGENTS.md 执行规范(AUTO-EXECUTE);interactive_menu.md 对应节。出站授权红线不变(默认端点白名单自动执行、自定义端点首次弹确认)。
- **本地引擎改为内部备用(2026-08-24)**:本地 R 兜底引擎(`adapters/local_engine.py` + `adapters/coze_project/src/r_engine/` 镜像)**代码保留**,但**不再对外文档说明**——README(中/英)、SKILL.md、interactive_menu.md 移除全部"本地引擎 / 本地兜底 / `prefer="local"` / 数据不出域可走本地"的用户导向表述,统一呈现为纯 coze 云端执行;AGENTS.md 标注 "internal only, not advertised"。本地兜底仅作 coze 不可用时的内部备用(不向用户宣传)。

---

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
89% confidence
Finding

Maintaining an auto-approved endpoint list reduces friction but weakens per-action consent controls for outbound communication. Even though the example references a bug-report endpoint, pre-authorizing remote destinations is dangerous in an agent skill because it can normalize silent data transmission and make endpoint abuse or misconfiguration harder for users to detect.

Content

Scanner excerpt · CHANGELOG.md (reported line 3792)May include surrounding context.

md
- **结果**:**44/46 通过**(含 2 个预期 `warn`:Egger 检验偏倚提示,属 Quality Gate 正常非阻断输出);**2 个失败 = dose_resp(case19 continuous / case45 binary),属 R 端 `run_dose_resp` dosresmeta NSE 集成缺陷,待修复 R 端代码**(见 Pending)。其余 44 例功能完整。

### Fixed / bug report 接入缺漏(ct-base §20.3.5)
- **问题**:`adapters/config.json` 的 `auto_approve_endpoints` 仅含 `https://ct-meta.coze.site/run`,**缺少**统一 bug-report 端点 `https://ct-bugreport.coze.site/run`,违反 §20.3.5(每个技能须将该端点列入自动批准白名单)。
- **修复**:`auto_approve_endpoints` 追加 `https://ct-bugreport.coze.site/run`。
- **已合规项确认**:`adapters/bug_report.py` 已含 §20.3.7 的 `confirm_thanks()` / `build_followup()` / `parse_history()`;SKILL.md §20.3 章节与 README §5/§20.3 出站披露均已就位。

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
89% confidence
Finding

This entry confirms automatic approval behavior for a remote bug-report endpoint, which can enable transmission without a fresh user decision at send time. In a skill that processes analysis data and operational metadata, that creates a meaningful risk of oversharing diagnostics or derived sensitive content to external services.

Content

Scanner excerpt · CHANGELOG.md (reported line 3793)May include surrounding context.

md
### Fixed / bug report 接入缺漏(ct-base §20.3.5)
- **问题**:`adapters/config.json` 的 `auto_approve_endpoints` 仅含 `https://ct-meta.coze.site/run`,**缺少**统一 bug-report 端点 `https://ct-bugreport.coze.site/run`,违反 §20.3.5(每个技能须将该端点列入自动批准白名单)。
- **修复**:`auto_approve_endpoints` 追加 `https://ct-bugreport.coze.site/run`。
- **已合规项确认**:`adapters/bug_report.py` 已含 §20.3.7 的 `confirm_thanks()` / `build_followup()` / `parse_history()`;SKILL.md §20.3 章节与 README §5/§20.3 出站披露均已就位。

### Pending / 待确认(非阻断,记入发布报告)

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
91% confidence
Finding

The documented auto_approve_endpoints model creates standing authorization for outbound requests, which is a security-sensitive design choice in an agent system. In this medical-analysis context, pre-approved remote execution endpoints increase the chance that user data, prompts, or derived results are sent automatically when the user may not expect it, especially after UI or workflow changes like auto-execute.

Content

Scanner excerpt · CHANGELOG.md (reported line 4116)May include surrounding context.

md
### Added / 新增(ct-base §5 coze 出站授权规范落地)

- **出站披露(§5 强制)**:SKILL.md 执行模型 + README/README_zh-CN 双份新增"数据将发送至 https://ct-meta.coze.site/run"披露声明(发送内容 = 分析数据,不含 PII);杜绝"出站却声称零出域"
- **首次出站授权门控(§5 AUTH-BLOCK 范式)**:`coze_client.py` 新增 `_auth_gate()` / `approve_endpoint()` / `AuthRequiredError`——端点不在白名单 → stderr 输出 AUTH-BLOCK + 统一确认文案(目标服务器/发送内容/本地资料有限说明);用户确认后写入 `adapters/config.json` `auto_approve_endpoints`(agent 绝不代写);默认端点已**作者预置**(正常用户无感),自定义端点才弹确认
- **未授权不阻断(§5)**:`run_analysis.py` 捕获 AuthRequiredError → 优先本地兜底(notes 注明"本次未使用云端分析");本地不可用返回 `_source=auth_blocked` 明确提示(授权问题可解决,不抛 RuntimeError)
- **出站 payload 脱敏(§5)**:`sanitize_payload()` 发送前剥离 PII(身份证/手机号/邮箱,递归清理嵌套结构)
- **agent 行为规则(§5 出站全程确认)**:SKILL.md 新增——forward 前**恰好一条**流程通知;coze 失败**先问用户**是否允许诊断,拒绝则交付本地答案 + 显著警告

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
adapters/llm_loader.py:52

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/build_request.py:65