T09 · Insecure Skill Coding Practices
- Location
orchestrator.py:469- Finding
Unsandboxed Execution of LLM-Generated Python Scripts
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This data-analysis skill is purpose-aligned, but it can run generated Python code with broad local permissions and stores potentially sensitive analysis prompts and reports on disk.
Install only if you are comfortable reviewing generated Python before execution, running it in a separate sandbox or container, using read-only least-privilege database credentials, and deleting saved prompt/report artifacts that may contain sensitive data.
orchestrator.py:469Unsandboxed Execution of LLM-Generated Python Scripts
report_generator.py:1016Stored HTML Injection in Generated Analysis Reports
| {key} | {value} |
Returning the fully assembled prompt exposes all embedded data to any caller, including sample values, inferred identifier fields, and potentially sensitive profiling context. In a skill whose purpose is data analysis via LLMs, prompt extraction is more dangerous because prompts are the exact carrier of confidential content intended for model submission and can be logged, displayed, or exfiltrated by upstream components.
# result = call_llm(prompt)
# return parse_ontology_result(result)
return prompt # 返回提示词供上层调用
def plan_analysis(self, ontology: OntologyResult, user_intent: str,
data_sample: str, column_details: List[str]) -> AnalysisPlan:
This method returns a prompt containing user intent, data samples, ontology details, and column metadata directly to the caller. That creates a straightforward disclosure path for sensitive operational context and undermines any future trust boundary between analysis logic and external consumers.
}
"""
return prompt
def generate_script(self, analysis_plan: AnalysisPlan, ontology: OntologyResult,
file_path: str) -> str:
The generated report prompt includes serialized analysis results and business/context metadata, then returns that prompt verbatim. Because prompts may contain confidential findings and derived insights, exposing them directly creates an unnecessary data leakage surface through logs, APIs, or downstream tooling.
请直接输出完整的Markdown报告。
"""
return prompt
def main():
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
# 交互模式:生成提示词供外部LLM使用
data_profile = self._generate_data_profile(primary_df)
prompt = self._build_ontology_prompt(data_profile)
return prompt
def _autonomous_ontology_inference(self, df: pd.DataFrame) -> DataOntology:
"""基于规则自动推断数据本体"""
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
# 交互模式:生成提示词供外部LLM使用
data_profile = self._generate_data_profile(primary_df)
prompt = self._build_ontology_prompt(data_profile)
return prompt
def _autonomous_ontology_inference(self, df: pd.DataFrame) -> DataOntology:
"""基于规则自动推断数据本体"""
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
# 交互模式:生成提示词供外部LLM使用
data_profile = self._generate_data_profile(primary_df)
prompt = self._build_ontology_prompt(data_profile)
return prompt
def _autonomous_ontology_inference(self, df: pd.DataFrame) -> DataOntology:
"""基于规则自动推断数据本体"""
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
# 交互模式:生成提示词供外部LLM使用
data_profile = self._generate_data_profile(primary_df)
prompt = self._build_ontology_prompt(data_profile)
return prompt
def _autonomous_ontology_inference(self, df: pd.DataFrame) -> DataOntology:
"""基于规则自动推断数据本体"""
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
# 交互模式:生成提示词供外部LLM使用
data_profile = self._generate_data_profile(primary_df)
prompt = self._build_ontology_prompt(data_profile)
return prompt
def _autonomous_ontology_inference(self, df: pd.DataFrame) -> DataOntology:
"""基于规则自动推断数据本体"""
The orchestrator presents itself as a data-analysis workflow but includes a step that executes an arbitrary external Python script, including one produced by an LLM in prior steps. In this skill context, that makes prompt-influenced code generation directly reachable to execution, enabling full remote code execution, data exfiltration, destructive file operations, or persistence if an attacker can influence the generated script or supplied path.
The skill explicitly describes generating and executing analysis scripts, yet provides no warning, consent step, or safety boundary around code execution and file creation. In this context, the risk is amplified by prompts that direct the LLM to output executable Python code and by the broad/automatic triggering model, creating a realistic path to unintended or unsafe autonomous actions on uploaded data.
The document is entirely written in Chinese and all example user intents, status labels, warnings, and output messages are specified in Chinese, including required manual LLM interaction instructions. This creates a natural-language locale constraint without any opt-in, alternative language option, or justification that the skill is region-specific.
Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
【重要提醒】
⚠️ 本体识别需要调用大模型完成!
⚠️ 提示词已保存到: session_xxx/step2_ontology_prompt.txt
Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
【重要提醒】
⚠️ 本体识别需要调用大模型完成!
⚠️ 提示词已保存到: session_xxx/step2_ontology_prompt.txt
The trigger phrases are broad enough to activate on ordinary requests like 'analyze this data' or 'explore this dataset,' which increases the chance of unintended invocation. In this skill, unintended activation is more dangerous because the workflow includes LLM-generated script creation, code execution, file writing, and potentially database access, so a casual request can escalate into high-trust automated actions without clear user acknowledgement.
The description states the system will generate executable Python scripts and run them, but it does not provide a user-facing warning about this behavior. That omission is dangerous because users may supply sensitive data or invoke the skill without understanding that arbitrary analysis code will be produced and executed, creating risks of unsafe execution, excessive resource use, or unintended side effects on the environment.
Advertising SQL database support via connection strings without a privacy and access warning can lead users to expose production or sensitive databases to an automated analysis workflow. In this context, the risk is amplified because the skill uses LLM-directed planning and script generation, so database interactions may retrieve, transform, or persist sensitive data in ways the user did not anticipate.
The output section shows that prompts, validation reports, cleaning reports, planning artifacts, scripts, and final reports are persisted to disk, but it does not warn that these artifacts may contain sensitive source data, schema details, credentials, or user instructions. This is especially risky for a data-analysis skill because uploaded datasets often include confidential business or personal information, and persistent artifacts broaden the exposure surface beyond the original session.
The file title and all explanatory content are written in Chinese, indicating a language-specific skill/update artifact with no visible opt-in or alternative locale guidance. This can violate language/locale policy when a skill implicitly requires a specific language without documenting user choice or regional justification.
The example workflow instructs the user to obtain a Python script from an LLM and then execute it via step6_execute_analysis("analysis_script.py"), but it does not present a clear warning that the generated code is untrusted and may perform arbitrary actions. In a skill context, this normalizes execution of AI-generated code, which can lead to local code execution, data exfiltration, filesystem damage, or abuse of network/system access if the generated script is malicious or unsafe.
This Python file contains user-facing natural-language strings and documentation entirely in Chinese, including the module description and all status/error text. That creates a locale/language policy concern because the skill appears to enforce a specific language without offering the user a choice or documenting a justified region-specific constraint.
The tool advertises itself as a generic file data loader, but it also supports SQL database connections and execution of arbitrary queries via user-supplied connection strings and SQL text. This mismatch is security-relevant because callers may permit the skill under the assumption that it only reads local files, while it can actually reach external/internal databases and perform broader data access than the description suggests.
The SQL path creates a database engine from a user-provided connection string and runs a user-provided query without any explicit warning that credentials may be transmitted and that network/database access may occur. In an agent setting, this can lead to unexpected access to internal services, exfiltration of sensitive data, or misuse of stored credentials because the action looks like ordinary data loading rather than a privileged external operation.
This Python file contains natural-language docstrings and user-facing output entirely in Chinese, including the module description and later report text. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation unless the constraint is justified as region-specific, which is not documented here.
The cleaning report is internally inconsistent: it computes a nonzero row-deletion estimate, then states both that all original data is retained and that the retained row count is 100%. In a data-cleaning pipeline, downstream users may trust the report rather than the actual actions taken, leading to silent data loss, incorrect audit records, or decisions made on misunderstood dataset scope.
The identify_ontology docstring says this step performs ontology recognition by invoking a large model, and its signature advertises an OntologyResult return value. In reality, the call is commented out and the function returns the raw prompt string at L180, which materially contradicts the documented behavior and intended effect.
No suspicious patterns detected.