Back to skill

Security audit

GuruTalk 大师云

Security checks for vulnerabilities and agentic risk

Overview

This is a real persona-skill manager, but it needs review because it can write and delete local skill folders and spread API keys without strong safeguards.

Review this before installing. Use it only with a Bibliotalk account/API key you are comfortable storing locally, avoid sending sensitive questions through generated personas, and do not run create/sync/remove with untrusted slugs. The publisher should add strict slug/path containment, deletion confirmation, endpoint validation, and avoid copying live `.env` secrets into generated skills.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/bibliotalk_client.py:66
Finding

Authenticated requests can be redirected to an arbitrary server

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/skill_writer.py:110
Finding

Plaintext API credentials are replicated into every generated Skill

Content
View full analysis
None: if not SOURCE_ENV_FILE.exists(): raise RuntimeError( f"Missing GuruTalk runtime env file: {SOURCE_ENV_FILE}. Run `python scripts/bibliotalk_client.py configure` in the current gurutalk skill directory first." ) scripts_dir = skill_dir / "scripts" scripts_dir.mkdir(parents=True, exist_ok=True) shutil.copy2(SOURCE_ENV_FILE, skill_dir / ".env") shutil.copy2(SOURCE_CLIENT_SCRIPT, scripts_dir / "bibliotalk_client.py") ``` This function is invoked when creating and synchronizing generated Skills: ```python (skill_dir / "SKILL.md").write_text(skill_md, encoding="utf-8") _copy_runtime_assets(skill_dir) ``` ### Technical Analysis The code copies the complete source `.env` file into every generated persona directory. This duplicates the Bibliotalk API key and may also copy unrelated configuration values that happen to be present in the source file. Credential replication is not necessary for the declared functionality. Generated Skills could reference one centrally managed credential instead. Each additional copy expands the number of files, backups, synchronization tools, processes, and users that may gain access to the secret. `copy2` also does not establish a deliberately restrictive destination mode; it preserves source metadata and therefore depends on the source file already having safe permissions. ### Attack Path 1. The user configures a Bibliotalk API key in the GuruTalk `.env`. 2. The user creates or synchronizes one or more personas. 3. `_copy_runtime_assets` copies the entire `.env` into each generated Skill. 4. A generated Skill directory is backed up, shared, archived, committed, or read by another local process. 5. The copied API key and any o ...[truncated 527 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/skill_writer.py:50
Finding

Generated personas transmit full user questions to an external service by default

Content
View full analysis
扮演 {display_name} 的技能。通过 `/{slug} {{message}}` 开始扮演;一旦开始,在后续对话中默认继续扮演 {display_name},直到用户发送 `/gurutalk end`,或通过 `/{{figure}} {{message}}` 切换人物。整个扮演期间,你发给用户的每条消息都必须以 `"{display_name}" Agent:\\n\\n` 开头,并且每次回答用户的问题前(如用户没有提问则视情况而定)必须先通过 query 接口搜索相关资料,然后在回答中给出忠实准确的引用。 user-invocable: true --- # {display_name} > 本技能由`gurutalk`技能生成与维护。资料来源:Bibliotalk 公有语料库检索与引用。 --- ## Profile {{{{include profile.md}}}} --- ## 对话规则 1. 你扮演 **{display_name}**。保持其思维方式、表达风格与个性特质。 2. 你发给用户的每条消息都必须以 `"{display_name}" Agent:\\n\\n` 开头。 3. 用户用什么语言,你回复的正文就用什么语言。 4. 先检索后回答:调用 1-5 次 `python scripts/bibliotalk_client.py query --figure {slug} --query "{{用户问题}}" --limit 5`。(所有命令以本技能文件夹为工作目录运行) 5. 如需核对某条引文详情,调用 `python scripts/bibliotalk_client.py quote --quote-id {quote_id}`。 6. 若当前技能目录下的 `.env` 缺少 `BIBLIOTALK_API_KEY`,提示用户在自己的命令行中运行 `python {SKILL_DIR}/scripts/bibliotalk_client.py configure`(插入本技能目录路径),然后按提示输入 API key。 7. `bibliotalk_client.py` 会自动读取当前技能目录下的 `.env`,不要拼接任何包含密钥的 shell 命令。 8. 关键判断必须引用 `kind=\"chunk\"` 的结果,并在句末标注 `[n]`。 9. `kind=\"memory\"` 只用于补充上下文,不得作为可溯源引用。 10. 若检索结果不足,明确降级:"关于这个问题,我目前缺少足够材料支撑。" 不要编造。 11. 将所有引用条目列于脚注中: ``` --- - [1]: ["原文片段"(不超过 10 字/词)](https://bibliotalk.space/q/:quote_id) - [2]: ... ``` """ ``` The client places the supplied question directly into the remote request body: ```python def query_figure( figure: str, query: str, *, limit: int | None = None, skill_dir: str | Path | None = None, ) -> dict[str, Any]: body: dict[str, Any] = { "figure": figure, "query": query, } if limit is not None: body["limi ...[truncated 1824 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Warning
Location
scripts/skill_writer.py:132
Finding

Untrusted remote profile content is loaded into the Agent’s instruction context

Content
View full analysis
str: display_name = str(detail.get("display_name", detail.get("slug", "Unknown"))) slug = str(detail.get("slug", "")) profile_version = str(detail.get("profile_version", "")) profile = detail.get("profile") or {} def s(key: str) -> str: v = profile.get(key, "") return str(v) if isinstance(v, str) else "" adjustments_block = adjustments if adjustments is not None else _default_adjustments() return ( f"# {display_name}\n\n" f"- slug: {slug}\n" f"- profile_version: {profile_version}\n\n" "## Identity\n" f"{s('identity')}\n\n" "## Mental Models\n" f"{s('mental_models')}\n\n" "## Expression Styles\n" f"{s('expr_styles')}\n\n" "## Personality\n" f"{s('personality')}\n\n" "## Timeline\n" f"{s('timeline')}\n\n" "## Adjustments\n" f"{adjustments_block.rstrip()}\n" ) ``` Creation fetches the data remotely and writes it without content validation: ```python detail = fetch_figure_detail(slug, skill_dir=PROJECT_ROOT) ``` ```python profile_md = build_profile_md(detail, adjustments=str(meta.get("adjustments") or _default_adjustments())) profile_path.write_text(profile_md, encoding="utf-8") display_name = str(detail.get("display_name", slug)) skill_md = build_guru_skill_md( slug=slug, display_name=display_name, headline=headline, ) (skill_dir / "SKILL.md").write_text(skill_md, encoding="utf-8") ``` The generated Skill includes that file in its active context: ```markdown ## Profile {{include profile.md}} ``` ### Tec ...[truncated 2185 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/skill_writer.py:207
Finding

Unsanitized slug permits path traversal, arbitrary writes, and recursive deletion

Content
View full analysis
Path: skill_dir = base_dir / slug if skill_dir.exists() and not force: raise RuntimeError(f"Guru directory already exists: {skill_dir} (use --force to overwrite)") runtime = load_runtime_config(skill_dir=PROJECT_ROOT, require_api_key=True) skill_dir.mkdir(parents=True, exist_ok=True) ``` Synchronization uses the same unsafe construction: ```python def guru_sync(base_dir: Path, *, slug: str) -> str: runtime = load_runtime_config(skill_dir=PROJECT_ROOT, require_api_key=True) skill_dir = base_dir / slug if not skill_dir.exists(): raise RuntimeError(f"Guru directory does not exist: {skill_dir}") ``` Removal recursively deletes the resulting path: ```python def guru_remove(base_dir: Path, *, slug: str) -> None: skill_dir = base_dir / slug if not skill_dir.exists(): raise RuntimeError(f"Guru directory does not exist: {skill_dir}") shutil.rmtree(skill_dir) ``` ### Technical Analysis The `slug` argument is accepted without a strict character policy or a resolved-path containment check. Python’s path joining behavior allows: - Traversal components such as `../`. - Nested paths containing separators. - Absolute paths that replace the intended `base_dir`. - Potential symlink-based escapes. As a result, create and synchronization operations can write `meta.json`, `profile.md`, `SKILL.md`, `.env`, and the copied client outside the intended Skills root. The remove action is more severe because it calls `shutil.rmtree` on the attacker-selected directory. The vulnerability is reachable through a docum ...[truncated 1118 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (31)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims end-user interaction features like persistent persona routing and enforced reply prefixes, yet those behaviors are not actually implemented in this file, while privileged filesystem/version-management actions are documented instead. That gap can conceal the true operational surface of the skill and cause users to approve it under false assumptions.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill claims end-user interaction features like persistent persona routing and enforced reply prefixes, yet those behaviors are not actually implemented in this file, while privileged filesystem/version-management actions are documented instead. That gap can conceal the true operational surface of the skill and cause users to approve it under false assumptions.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims end-user interaction features like persistent persona routing and enforced reply prefixes, yet those behaviors are not actually implemented in this file, while privileged filesystem/version-management actions are documented instead. That gap can conceal the true operational surface of the skill and cause users to approve it 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 22)May include surrounding context.

md
5. 确保每个独立技能文件夹里至少包含:`meta.json`、`SKILL.md`、`profile.md`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
5. 确保每个独立技能文件夹里至少包含:`meta.json`、`SKILL.md`、`profile.md`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
5. 确保每个独立技能文件夹里至少包含:`meta.json`、`SKILL.md`、`profile.md`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
5. 确保每个独立技能文件夹里至少包含:`meta.json`、`SKILL.md`、`profile.md`

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/bibliotalk_client.py (reported line 8)May include surrounding context.

python
`.env` file. When copied into a generated figure skill, it keeps working with the
same relative layout:

- <skill_dir>/.env
- <skill_dir>/scripts/bibliotalk_client.py
"""

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/bibliotalk_client.py (reported line 59)May include surrounding context.

python
DEFAULT_AGENT = "claude"
DEFAULT_GURU_BASE_DIR = None  # Reserved for explicit overrides when needed
PROJECT_ROOT = Path(__file__).resolve().parent.parent
SOURCE_ENV_FILE = PROJECT_ROOT / ".env"
SOURCE_CLIENT_SCRIPT = PROJECT_ROOT / "scripts" / "bibliotalk_client.py"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/skill_writer.py (reported line 46)May include surrounding context.

python
DEFAULT_AGENT = "claude"
DEFAULT_GURU_BASE_DIR = None  # Reserved for explicit overrides when needed
PROJECT_ROOT = Path(__file__).resolve().parent.parent
SOURCE_ENV_FILE = PROJECT_ROOT / ".env"
SOURCE_CLIENT_SCRIPT = PROJECT_ROOT / "scripts" / "bibliotalk_client.py"

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

shutil.copy2(SOURCE_ENV_FILE, skill_dir / ".env") duplicates a live credential file into each generated skill, expanding the number of locations where secrets exist. In the context of a tool that mass-generates persona skills, this significantly widens the blast radius of any local compromise, accidental sharing, or malicious modification of generated skill directories.

Content

Scanner excerpt · scripts/skill_writer.py (reported line 119)May include surrounding context.

python
scripts_dir = skill_dir / "scripts"
    scripts_dir.mkdir(parents=True, exist_ok=True)

    shutil.copy2(SOURCE_ENV_FILE, skill_dir / ".env")
    shutil.copy2(SOURCE_CLIENT_SCRIPT, scripts_dir / "bibliotalk_client.py")

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

guru_remove permanently deletes the target skill directory using shutil.rmtree, which is a destructive filesystem operation. The code path provides no confirmation prompt and no inline warning describing the irreversible deletion behavior before it executes.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The natural-language instructions, examples, and usage guidance are all presented in Chinese, which effectively forces a specific language for users. The file does not offer an opt-in choice of language or explain that the skill is intended only for a Chinese-speaking or region-specific audience.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs the agent to perform network access, read/write local files, and handle secrets in .env, but it does not declare any permissions or allowed-tools scope. That mismatch weakens least-privilege boundaries and makes it easier for a broadly privileged runtime to execute filesystem and network actions the user may not expect.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
70% confidence
Finding

This duplicate finding reflects the same persistence concern: installation generates long-lived files in agent skill directories, including configuration and executable-support artifacts. If users believe they are only starting a temporary conversation flow, this persistent modification can create ongoing exposure and configuration drift.

Content

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

执行:

bash
python scripts/skill_writer.py --action guru-create --agent {agent} --slug {slug}

安装后会生成:

Session Persistence

Medium
Category
Rogue Agent
Confidence
70% confidence
Finding

This duplicate finding reflects the same persistence concern: installation generates long-lived files in agent skill directories, including configuration and executable-support artifacts. If users believe they are only starting a temporary conversation flow, this persistent modification can create ongoing exposure and configuration drift.

Content

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

执行:

bash
python scripts/skill_writer.py --action guru-create --agent {agent} --slug {slug}

安装后会生成:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill describes deleting local persona directories without any warning, preview, or explicit confirmation requirement. In a skill that manages files under user skill directories, an accidental or ambiguous invocation could permanently remove installed content or customized profiles.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

md
## 备注

- 工作目录(`pwd`)为 `gurutalk` 技能的目录
- 每个大师作为一个独立的技能安装在对应 agent 的 skills 目录中:`~/.claude/skills/{slug}/`、`~/.openclaw/workspace/skills/{slug}/`、`~/.codex/skills/{slug}/`
- 每个技能目录都应保有自己的 `.env` 与 `scripts/bibliotalk_client.py`
- 一旦进入某个人物对话,后续消息默认继续发给该人物,直到用户发送 `/gurutalk end`,或通过 `/{another-figure} {message}` 直接切换
- 使用 `--agent` 参数指定目标 agent 类型:`claude`、`openclaw` 或 `codex`

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

md
## 备注

- 工作目录(`pwd`)为 `gurutalk` 技能的目录
- 每个大师作为一个独立的技能安装在对应 agent 的 skills 目录中:`~/.claude/skills/{slug}/`、`~/.openclaw/workspace/skills/{slug}/`、`~/.codex/skills/{slug}/`
- 每个技能目录都应保有自己的 `.env` 与 `scripts/bibliotalk_client.py`
- 一旦进入某个人物对话,后续消息默认继续发给该人物,直到用户发送 `/gurutalk end`,或通过 `/{another-figure} {message}` 直接切换
- 使用 `--agent` 参数指定目标 agent 类型:`claude`、`openclaw` 或 `codex`

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file’s title and all operational instructions are written in Chinese, and the required output format is specified only in Chinese. This imposes a language/locale constraint on the skill without any opt-in, alternative language path, or documented justification for why the skill must operate only in Chinese.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The instruction 语言:中文 mandates a specific language for all outputs. The file does not offer a language choice, user opt-in, or a documented region-specific reason for this constraint, which matches the locale-policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The entire instruction file is written in Chinese and specifies output behavior in Chinese without offering any language choice or explaining that the skill is intended only for a Chinese-language context. This creates a natural-language locale policy concern because the skill appears to impose a specific language by default.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code performs an HTTP request that transmits a user email address as a query parameter, but there is no confirmation prompt or user-facing warning at the point of transmission. For code files, network calls that send user data should have some visible disclosure unless the behavior is clearly warned elsewhere.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Several user-facing help texts and error messages are hard-coded in Chinese, which imposes a specific language on all users. The policy allows locale constraints only when opt-in is provided or the restriction is clearly documented and justified, neither of which appears in this file.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script copies the parent skill's .env file into every generated persona skill directory, propagating API keys and other secrets far beyond their original trust boundary. In a skill ecosystem where generated skills may be inspected, synced, backed up, or modified separately, duplicating secrets materially increases the chance of credential disclosure and misuse.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.