T01 · Skill Instruction Hijacking
- Location
analyzer.py:48- Finding
Indirect Prompt Injection Through Recording Summaries
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill fits its dashboard purpose but needs Review because it handles sensitive recording-derived business data with insecure network and report-rendering defaults.
Install only in a controlled environment after narrowing triggers, forcing HTTPS for the recording API, adding host/path/tool allowlists, escaping or templating all report output, bundling or integrity-pinning Chart.js, bounding pagination, and documenting how recording summaries, LLM prompts, and generated HTML reports are retained and protected.
analyzer.py:48Indirect Prompt Injection Through Recording Summaries
html_generator.py:441Stored HTML and JavaScript Injection in Generated Reports
销冠行为描述:{performer.get('behavior_description', '')}
{suggestion.get('content', '')}
html_generator.py:793Script-Element Breakout Through Unsafe JSON Embedding
config.py:14Sensitive Identifiers and Recording Data Transmitted Over Plaintext HTTP
html_generator.py:586Remote Executable JavaScript Loaded Without Integrity Verification
main.py:265Unbounded Pagination Allows Resource-Exhaustion Attacks
requirements.txt:1Python Dependency Is Not Reproducibly Pinned
代码与声明存在实质性不匹配。声明描述的是一个完整的“管理驾驶舱日报生成”技能,包含数据获取、身份解析、LLM 分析以及最终 HTML 可视化报表输出;而实际代码只是其中的一个子模块:基于已提供的 contents 和 context 生成结构化 JSON 分析结果。虽然六大分析板块与声明中的分析目标基本一致,说明代码覆盖了“LLM 分析”这一部分,但缺失了声明中强调的关键能力和流程,包括 API 拉取、agentId 解析、HTML 报表生成和入口约束。因此,实际行为更像是“分析器组件”,而不是声明中的完整技能实现。
The code’s output format loosely aligns with the declared domain because it generates an HTML report structure with the same broad sections and supports the 'empty contents still generates HTML report' idea. However, the actual behavior in this chunk is materially different from the declared purpose: it is a test utility that creates a mock zero-value report using static data. None of the key declared workflow steps are present—no session_status lookup, no paginated API access, no ai_summary_content handling, no LLM analysis, and not even the declared main.py entry point. This is a substantial description-versus-behavior mismatch, even if the script may be a supporting test artifact within a larger project.
该代码片段的核心行为是“用预置样例数据生成一份测试 HTML 报表”。虽然输出形式与声明中的“生成管理者日报 HTML 报表”表面相关,但其主要实现缺失了声明中最关键的数据来源与处理链路:会话态解析 agentId、分页拉取录音 AI 摘要、LLM 分析六大板块内容。代码也不符合声明中的运行约束(main.py 唯一入口)。因此,这不是仅仅展示某个支持性子模块,而是表现出与声明主功能明显不一致的实际行为:测试数据报表生成脚本,而非完整的管理驾驶舱技能实现。
该代码块的实际职责是报表渲染器/导出器,而不是完整的“管理驾驶舱技能”主流程。它确实与声明中的一部分相符——会生成管理驾驶舱/系统驾驶舱风格的 HTML 可视化报表,并支持空数据情况下仍生成 HTML。但声明中的关键前置和核心能力均未在代码中出现:没有解析 sessionKey/current 得到 agentId,没有访问任何外部 API 或分页拉取 ai_summary_content,也没有调用 LLM 对录音摘要做分析;相反,代码假定 analysis 已经事先生成完毕,仅负责展示和保存。因此,若将声明与这段代码直接比对,描述显著高于并偏离了该代码块实际功能,构成明显不匹配。
整体业务方向基本一致:代码确实用于管理驾驶舱日报/报表生成,使用分页接口拉取录音摘要,并输出 HTML,空数据也会生成报表,这些与声明大体相符。但存在两处关键描述与实现不一致。第一,声明中明确写了“MUST resolve agentId via session_status (sessionKey=current) before APIs”,而实际代码完全没有 session_status 调用逻辑,execute 直接把 agent_id 作为入参传给后续接口,因此这一必需前置步骤未实现。第二,声明强调‘通过 LLM 分析生成’六大板块报表,但 _get_llm_client 中只是伪代码说明,真实 chat 实际调用 _mock_response,返回固定的零值 JSON,用于测试;这意味着当前代码并未真正执行所宣称的 LLM 分析能力。除此之外,没有发现明显的额外未声明高风险能力;网络访问也与获取录音数据/生成报表的目的基本一致。因此应判定为存在描述-行为不匹配。
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
请确保返回的是合法的 JSON 格式,不要包含其他文字说明。
"""
return prompt
def _validate_result(self, result: Dict[str, Any]) -> Dict[str, Any]:
"""验证并补全结果"""
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
rm_section = ''
if chart_source:
rm_section += """ <div class="chart-container">
<h3 style="margin-top:0;display:flex;align-items:center;gap:6px;"><svg class="metric-icon" viewBox="0 0 24 24" fill="none" stroke="#667eea" stroke-width="2"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg>RM 得分排行</h3>
<canvas id="rmScoreChart"></canvas>
</div>
"""
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
rm_section = ''
if chart_source:
rm_section += """ <div class="chart-container">
<h3 style="margin-top:0;display:flex;align-items:center;gap:6px;"><svg class="metric-icon" viewBox="0 0 24 24" fill="none" stroke="#667eea" stroke-width="2"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg>RM 得分排行</h3>
<canvas id="rmScoreChart"></canvas>
</div>
"""
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
<!-- 当日 RM 业务水平 -->
<div class="section">
<h2><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="#667eea" stroke-width="2"><path d="M6 9H4.5a2.5 2.5 0 0 1 0-5C7 4 7 7 7 7"/><path d="M18 9h1.5a2.5 2.5 0 0 0 0-5C17 4 17 7 17 7"/><path d="M4 22h16"/><path d="M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20.24 7 22"/><path d="M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22"/><path d="M18 2H6v7a6 6 0 0 0 12 0V2Z"/></svg>第三板块:当日 RM 业务水平</h2>
<h3 style="display:flex;align-items:center;gap:6px;"><svg class="metric-icon" viewBox="0 0 24 24" fill="none" stroke="#667eea" stroke-width="2"><path d="M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z"/></svg>今日团队沟通技能得分排行(百分制)</h3>
{rm_section}{rm_score_table} </div>
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
<!-- 当日 RM 业务水平 -->
<div class="section">
<h2><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="#667eea" stroke-width="2"><path d="M6 9H4.5a2.5 2.5 0 0 1 0-5C7 4 7 7 7 7"/><path d="M18 9h1.5a2.5 2.5 0 0 0 0-5C17 4 17 7 17 7"/><path d="M4 22h16"/><path d="M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20.24 7 22"/><path d="M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22"/><path d="M18 2H6v7a6 6 0 0 0 12 0V2Z"/></svg>第三板块:当日 RM 业务水平</h2>
<h3 style="display:flex;align-items:center;gap:6px;"><svg class="metric-icon" viewBox="0 0 24 24" fill="none" stroke="#667eea" stroke-width="2"><path d="M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z"/></svg>今日团队沟通技能得分排行(百分制)</h3>
{rm_section}{rm_score_table} </div>
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
<!-- 当日 RM 业务水平 -->
<div class="section">
<h2><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="#667eea" stroke-width="2"><path d="M6 9H4.5a2.5 2.5 0 0 1 0-5C7 4 7 7 7 7"/><path d="M18 9h1.5a2.5 2.5 0 0 0 0-5C17 4 17 7 17 7"/><path d="M4 22h16"/><path d="M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20.24 7 22"/><path d="M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22"/><path d="M18 2H6v7a6 6 0 0 0 12 0V2Z"/></svg>第三板块:当日 RM 业务水平</h2>
<h3 style="display:flex;align-items:center;gap:6px;"><svg class="metric-icon" viewBox="0 0 24 24" fill="none" stroke="#667eea" stroke-width="2"><path d="M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z"/></svg>今日团队沟通技能得分排行(百分制)</h3>
{rm_section}{rm_score_table} </div>
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
The skill is documented to automatically retrieve recording AI summaries and save generated reports to disk, but it does not clearly warn about sensitive data handling, retention, access control, or local storage risks. In this context, the report likely contains employee performance, compliance, and customer-related summaries, so silent processing and persistence can expose regulated or confidential data if operators are unaware of the storage behavior.
该 README 明确将“日报生成”列为触发词,但这是一个通用表达,并未限定为管理驾驶舱或录音分析场景。文档也没有给出排除条件或负例,因此容易与普通“生成日报”请求重叠。
The skill describes access to environment variables, local file reads/writes, and outbound network/API calls, but it declares no explicit tool scope such as permissions or allowed-tools. In an agent platform, that omission weakens least-privilege controls and can allow the runtime to grant broader capabilities than users or reviewers expect.
The trigger phrases include broad terms like '日报生成' and '团队分析', which can overlap with normal user requests and cause the skill to activate unexpectedly. Over-broad activation increases the chance of unnecessary data retrieval, unintended report generation, or routing sensitive business queries into a networked/reporting workflow without clear user intent.
The skill explicitly instructs outbound transmission of conversation-derived business data to an external recording API and then to an LLM for analysis. Even if intended, this is security-relevant because ai_summary_content may contain sensitive customer, employee, compliance, or call-summary data, and the spec does not show minimization, host allowlisting, consent, or redaction controls.
4. **按 [用户回复规范](#用户回复规范) 返回结果**。
> **禁止**跳过 `main.py` 自行 curl 后在空数据时文字回复;
---
The paginated curl example repeatedly sends agentId, time window, and retrieves potentially sensitive AI summaries from an external service. In this skill context, external transmission is expected, but it remains dangerous without access control checks, endpoint restrictions, and safeguards against overcollection or leakage of confidential recording-derived data.
# 若 completed=false,继续请求下一页(使用相同的 UUID)
PAGE=2
while [ "$COMPLETED" = "False" ] || [ "$COMPLETED" = "false" ]; do
curl -sS -X POST "${API_BASE_URL}/api/recordings/asr-completed/page" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d "{\"agentId\":\"${AGENTID}\",\"uuid\":\"${UUID}\",\"startTime\":\"${START_TIME}\",\"endTime\":\"${END_TIME}\"}" \
The code sends potentially sensitive recording summaries and speaker names to an LLM via self.llm_client.chat(prompt) without any visible consent, disclosure, minimization, or policy gate. In this skill context, the data appears to be internal management, compliance, and sales activity content, which can contain employee and customer-sensitive information, making undisclosed model transmission a real privacy and governance risk.
The file’s user-facing natural-language content, including the module docstring, status output, and all report text literals, is written exclusively in Chinese with no indication that language selection is optional. Under the policy, forcing a specific language without user choice is a natural-language policy violation unless the locale constraint is explicitly documented and justified.
The file's natural-language content and generated report are hard-coded in Chinese, including lang="zh-CN" and all user-facing labels, with no indication that the user can choose another language. This is a language/locale policy violation under the stated rules because the skill enforces a specific locale without opt-in or documented justification.
The generated HTML unconditionally loads Chart.js from a public CDN, which introduces an external network dependency and a third-party script execution path whenever the report is opened. If the CDN is unavailable, compromised, blocked, or swapped via DNS/TLS interception, the report can fail or run attacker-controlled JavaScript in the viewer's browser.
The report causes network access to a third-party CDN when opened, but the generated HTML provides no disclosure to the user that opening a local report will contact an external service. In a reporting skill that may handle sensitive business summaries, this increases privacy and supply-chain risk because users may assume the report is fully local.
This code generates and saves an HTML report to disk via write_html_file(file_path, html), but there is no confirmation prompt, visible logging, or user-facing notice in this file indicating that a file will be created. Because file creation can affect user data and filesystem state, the lack of disclosure meets the missing-warning criterion for code files.