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

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

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

专为初高中学生家长设计的智能学习陪伴�
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

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
Content
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请回答以下问题,为孩子创建学习档案:
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
def run_command(cmd):
    """运行命令并返回结果"""
    try:
        result = subprocess.run(
            cmd,
            shell=True,
            capture_output=True,
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.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
shell=True,
            capture_output=True,
            text=True,
            env=os.environ.copy(),
            timeout=5
        )
        return result.returncode == 0, result.stdout, result.stderr
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.

Natural-Language Policy Violations

Medium
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.

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Natural-Language Policy Violations

Medium
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.

Missing User Warnings

Medium
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.

Natural-Language Policy Violations

Medium
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.

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

Medium
Category
Data Flow
Content
def save_profile(profile):
    """保存用户档案"""
    with open(PROFILE_FILE, 'w', encoding='utf-8') as f:
        json.dump(profile, f, ensure_ascii=False, indent=2)
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.

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

Medium
Category
Data Flow
Content
# 保存计划
    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']}学习计划已生成!")
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.

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

Medium
Category
Data Flow
Content
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("✅ 打卡成功!")
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.

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

Medium
Category
Data Flow
Content
}
    
    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}")
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.

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

Medium
Category
Data Flow
Content
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("✅ 错题已记录")
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.

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

Medium
Category
Data Flow
Content
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("⚠️  未找到该错题")
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.

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

Medium
Category
Data Flow
Content
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("⚠️  未找到该错题")
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.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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)
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Medium
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.

Natural-Language Policy Violations

Medium
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.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def run_command(cmd):
    """运行命令并返回结果"""
    try:
        result = subprocess.run(
            cmd,
            shell=True,
            capture_output=True,
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.

Natural-Language Policy Violations

Low
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.

Natural-Language Policy Violations

Low
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.

Static analysis

No suspicious patterns detected.