Back to skill

Security audit

Study Buddy

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed local study-tracking tool that stores study data on the user's machine and does not show evidence of hidden network access, exfiltration, or unsafe persistence.

Install only if you are comfortable storing a child's study profile, learning logs, wrong-question entries, and reports as local JSON files. Use STUDY_BUDDY_HOME for an isolated directory on shared machines, and delete the local data directory when you no longer want the records retained.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

声明描述的是面向家长和学生学习管理场景的用户功能,但实际代码并未实现任何学习计划、学习打卡、错题记录或学习报告相关逻辑。相反,这段代码仅用于项目发布前的工程校验与测试执行,属于开发/运维辅助功能,主目的与声明明显不一致。虽然这可能是仓库中的辅助脚本,但就所给代码片段本身而言,其行为与技能声明存在明显描述-行为不匹配。

Content

No source excerpt is available for this finding.

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

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

md
---
name: study-buddy
description: 初高中学生家长的学习陪伴助手,帮助家长为孩子制定学习计划、追踪学习进度、管理错题本、生成学习报告。适用于家长辅导孩子学习、监督学习进度、记录学习成果。触发词包括"帮我制定学习计划"、"孩子学习打卡"、"查看学习进度"、"记录错题"、"生成学习报告"。
version: 1.2.0
author: jianghaidong
runtime:
  permissions:
    filesystem: true
  requires:
    python: ">=3.8"
---

# Study Buddy - 初高中学生家长学习陪伴助手

专为初高中学生家长设计的智能学习陪伴�

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · scripts/study-buddy.py (reported line 76)May include surrounding context.

python
dy.py wrong add "二次函数求根错误" --subject "数学"
  python3 scripts/study-buddy.py report

数据存储:~/.study-buddy/(可用 STUDY_BUDDY_HOME 覆盖)
    """)


def cmd_start():
    """开始学习之旅 - 交互式收集学习背景(家长视角)"""
    print("🎯 欢迎使用 Study Buddy - 初高中学生家长学习陪伴助手!")
    print("=" * 50)
    print("\n👨‍👩‍👧 本工具帮助家长科学管理孩子的学习过程")
    print("   让我们一起为孩子建立学习档案...")
    
    profile = load_profile()
    if profile:
        print(f"\n📋 发现已有学习档案:{profile.get('student_name', '孩子')} - {profile.get('subject', '未设置')}")
        overwrite = input("是否重新设置?(y/N): ").strip().lower()
        if overwrite != 'y':
            print("保持现有设置。使用 /study-buddy today 查看今日任务。")
            return
    
    print("\n请回答以下问题,为孩子创建学习档案:

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

The subprocess helper accepts a raw command string and runs it with shell=True, enabling shell parsing and expansion. Even though the current tests call it with fixed literals, this pattern is a classic command-injection sink and becomes exploitable if future code passes user input, file names, environment-derived values, or repository-controlled strings into cmd.

Content

Scanner excerpt · test/test_commands.py (reported line 14)May include surrounding context.

python
def run_command(cmd):
    """运行命令并返回结果"""
    try:
        result = subprocess.run(
            cmd,
            shell=True,
            capture_output=True,

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · test/test_commands.py (reported line 19)May include surrounding context.

python
shell=True,
            capture_output=True,
            text=True,
            env=os.environ.copy(),
            timeout=5
        )
        return result.returncode == 0, result.stdout, result.stderr

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill description, headings, and user instructions are entirely in Chinese, which effectively imposes a specific language on users. The file does not offer an alternative language option or state that the tool is intentionally limited to a Chinese-speaking or region-specific audience for compliance or other justified reasons.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file consistently presents the skill name, description, usage guidance, and safety information only in Chinese. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly justified, which is not documented here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly collects and stores a child’s study profile, learning logs, wrong-question history, and parent notes under a local directory, but the documentation provides no privacy notice, retention policy, consent guidance, or warning that potentially sensitive child-related data will be persisted. In a parent/child education context, this increases the risk of unintended collection and long-term storage of minors’ personal and behavioral data without informed user awareness.

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 skill contains user-facing descriptions and prompts entirely in Chinese, starting with the title line, and nowhere offers an alternate language or asks the user to opt into Chinese. Under the language/locale policy, forcing a specific language without user choice is a natural-language policy violation unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Tainted flow: 'PROFILE_FILE' from os.environ.get (line 15, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/study-buddy.py (reported line 39)May include surrounding context.

python
def save_profile(profile):
    """保存用户档案"""
    with open(PROFILE_FILE, 'w', encoding='utf-8') as f:
        json.dump(profile, f, ensure_ascii=False, indent=2)

Tainted flow: 'plan_file' from os.environ.get (line 219, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/study-buddy.py (reported line 220)May include surrounding context.

python
# 保存计划
    plan_file = PLANS_DIR / f"plan_{datetime.now().strftime('%Y%m%d')}.json"
    with open(plan_file, 'w', encoding='utf-8') as f:
        json.dump(plan, f, ensure_ascii=False, indent=2)
    
    print(f"\n📋 {profile.get('student_name', '孩子')}的{profile['subject']}学习计划已生成!")

Tainted flow: 'log_file' from os.environ.get (line 353, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/study-buddy.py (reported line 332)May include surrounding context.

python
existing = [existing, log_entry]
        log_entry = existing
    
    with open(log_file, 'w', encoding='utf-8') as f:
        json.dump(log_entry, f, ensure_ascii=False, indent=2)
    
    print("✅ 打卡成功!")

Tainted flow: 'report_file' from os.environ.get (line 652, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/study-buddy.py (reported line 653)May include surrounding context.

python
}
    
    report_file = DATA_DIR / f"report_{datetime.now().strftime('%Y%m%d')}.json"
    with open(report_file, 'w', encoding='utf-8') as f:
        json.dump(report_data, f, ensure_ascii=False, indent=2)
    
    print(f"\n✅ 报告已保存: {report_file}")

Tainted flow: 'wrong_file' from os.environ.get (line 696, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/study-buddy.py (reported line 686)May include surrounding context.

python
wrong_list.append(wrong_entry)
        
        with open(wrong_file, 'w', encoding='utf-8') as f:
            json.dump(wrong_list, f, ensure_ascii=False, indent=2)
        
        print("✅ 错题已记录")

Tainted flow: 'wrong_file' from os.environ.get (line 763, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/study-buddy.py (reported line 756)May include surrounding context.

python
break
        
        if found:
            with open(wrong_file, 'w', encoding='utf-8') as f:
                json.dump(wrong_list, f, ensure_ascii=False, indent=2)
        else:
            print("⚠️  未找到该错题")

Tainted flow: 'wrong_file' from os.environ.get (line 763, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/study-buddy.py (reported line 781)May include surrounding context.

python
break
        
        if found:
            with open(wrong_file, 'w', encoding='utf-8') as f:
                json.dump(wrong_list, f, ensure_ascii=False, indent=2)
        else:
            print("⚠️  未找到该错题")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/verify.py (reported line 16)May include surrounding context.

python
def run(cmd):
    result = subprocess.run(cmd, cwd=ROOT, text=True, capture_output=True)
    if result.returncode != 0:
        print(result.stdout)
        print(result.stderr, file=sys.stderr)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest sets "language": "zh", which indicates a fixed language choice. Under the policy, forcing a specific language without offering user choice or documenting a justified locale constraint 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
97% confidence
Finding

This Python file contains natural-language strings entirely in Chinese, including the module docstring and all user-facing test output/messages, with no indication that users can opt into another language. The policy specifically flags language or locale constraints when a skill forces a specific language without user choice or documented justification.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
96% confidence
Finding

The test helper executes shell commands via subprocess.run(..., shell=True), which is inherently risky because any untrusted or unexpectedly modified command string can trigger shell metacharacter interpretation and arbitrary command execution. In this file the current callers pass constant strings, so the immediate exploitability is limited, but the helper is generic and creates an unsafe pattern that can become dangerous if reused with variable input or if command components become attacker-controlled.

Content

Scanner excerpt · test/test_commands.py (reported line 14)May include surrounding context.

python
def run_command(cmd):
    """运行命令并返回结果"""
    try:
        result = subprocess.run(
            cmd,
            shell=True,
            capture_output=True,

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

All natural-language instructions, command descriptions, and examples are presented only in Chinese, with no indication that users may choose another language. The policy requires flagging language or locale constraints when they are imposed without user opt-in or clear justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The markdown content is entirely written in Chinese and presents the skill artifacts and command descriptions only in that language. Under the stated policy, language constraints should either offer user opt-in/choice or be explicitly justified as region-specific; neither is present in this file.

Content

No source excerpt is available for this finding.