Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
React-Router-CVE-2025-61686- — 关于 CVE-2025-61686 的详细分析,这是 React Router 文件会话存储中的一个路径遍历漏洞,涵盖根本原因、攻击场景及代码审计发现。 | Kitploit
工具/GitHubGitHub/kai-one001/react-router-cve-2025-61686-
静态分析漏洞分析代码分析漏洞利用Web安全学习与教育
GitHubkai-one001/react-router-cve-2025-61686-

React-Router-CVE-2025-61686-

关于 CVE-2025-61686 的详细分析,这是 React Router 文件会话存储中的一个路径遍历漏洞,涵盖根本原因、攻击场景及代码审计发现。

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
查看仓库
27个月前尚未审核

CVE-2025-61686 漏洞分析报告

漏洞概述

CVE ID: CVE-2025-61686
影响版本: @react-router/node 7.0.0 至 7.9.3
漏洞类型: 路径遍历 (Path Traversal) / 目录穿越

漏洞原理

1. 漏洞位置

漏洞存在于 packages/react-router-node/sessions/fileStorage.ts 文件中的 getFile() 函数和相关的文件操作逻辑。

2. 核心问题分析

2.1 Session ID 的来源

在 packages/react-router/lib/server-runtime/sessions.ts 的第 267 行:

root@kitploit:~
async getSession(cookieHeader, options) {
  let id = cookieHeader && (await cookie.parse(cookieHeader, options));
  let data = id && (await readData(id));
  return createSession(data || {}, id || "");
}

Session ID 从 Cookie 中解析而来,通过 cookie.parse() 方法。

2.2 Cookie 解析逻辑

在 packages/react-router/lib/server-runtime/cookies.ts 的 decodeCookieValue() 函数中:

root@kitploit:~
async function decodeCookieValue(
  value: string,
  secrets: string[],
): Promise<any> {
  if (secrets.length > 0) {
    // 如果配置了 secrets,会验证签名
    for (let secret of secrets) {
      let unsignedValue = await unsign(value, secret);
      if (unsignedValue !== false) {
        return decodeData(unsignedValue);
      }
    }
    return null;  // 签名验证失败返回 null
  }
  
  // 如果没有配置 secrets(未签名),直接返回解码后的值
  return decodeData(value);
}

关键问题:当 cookie 未签名(secrets 为空数组或未设置)时,decodeCookieValue 会直接返回解码后的 cookie 值,攻击者可以完全控制这个值。

2.3 路径构建逻辑

在 packages/react-router-node/sessions/fileStorage.ts 中:

root@kitploit:~
export function getFile(dir: string, id: string): string {
  // Divide the session id up into a directory (first 2 bytes) and filename
  // (remaining 6 bytes) to reduce the chance of having very large directories,
  return path.join(dir, id.slice(0, 4), id.slice(4));
}

该函数将 session ID 分成两部分:

  • 前 4 个字符作为目录名:id.slice(0, 4)
  • 剩余字符作为文件名:id.slice(4)

然后使用 path.join() 拼接路径。

2.4 漏洞利用方式

攻击场景:当使用 createFileSessionStorage() 且 cookie 未签名时:

  1. 攻击者可以构造恶意的 session ID,例如:../../etc/passwd
  2. getFile() 函数处理:
    • id.slice(0, 4) = ../.
    • id.slice(4) = /etc/passwd
    • path.join(dir, ../., /etc/passwd)
    • 虽然 path.join() 会规范化路径,但如果 dir 已经是相对路径或经过处理后,仍可能实现路径遍历

更精确的利用方式:

  • Session ID: ....//etc/passwd
    • id.slice(0, 4) = ....
    • id.slice(4) = //etc/passwd
    • 如果处理不当,可能导致访问 /etc/passwd

或者:

  • Session ID: ../../../etc/passwd(16字符)
    • id.slice(0, 4) = ../.
    • id.slice(4) = ./etc/passwd
    • 结合 path.join() 的行为,可能导致路径遍历

3. 受影响的操作

以下文件操作都可能受影响:

  1. readData(id) - 读取会话数据时

    root@kitploit:~
    async readData(id) {
      try {
        let file = getFile(dir, id);
        let content = JSON.parse(await fsp.readFile(file, "utf-8"));
        // ...
      }
    }
    
  2. updateData(id, data, expires) - 更新会话数据时

    root@kitploit:~
    async updateData(id, data, expires) {
      let content = JSON.stringify({ data, expires });
      let file = getFile(dir, id);
      await fsp.mkdir(path.dirname(file), { recursive: true });
      await fsp.writeFile(file, content, "utf-8");
    }
    
  3. deleteData(id) - 删除会话数据时

    root@kitploit:~
    async deleteData(id) {
      try {
        await fsp.unlink(getFile(dir, id));
      }
    }
    

4. 攻击影响

  1. 文件读取:攻击者可能读取服务器上的任意文件(取决于 Web 服务器进程的权限)
  2. 文件写入:攻击者可能在服务器上写入文件,可能导致:
    • 数据泄露
    • 代码注入
    • 权限提升
  3. 文件删除:攻击者可能删除服务器上的文件

5. 漏洞触发条件

必须同时满足以下条件:

  1. 使用 createFileSessionStorage() 方法
  2. Cookie 未签名(cookie 配置中未设置 secrets 或 secrets 为空数组)
  3. Web 服务器进程对目标文件有读写权限

代码审计发现

关键代码路径

root@kitploit:~
getSession(cookieHeader) 
  → cookie.parse(cookieHeader) 
    → decodeCookieValue(value, secrets)  // 未签名时直接返回 value
      → readData(id) 
        → getFile(dir, id)  // 路径拼接,存在路径遍历风险
          → fsp.readFile(file) / fsp.writeFile(file) / fsp.unlink(file)

问题根源

  1. 缺少输入验证:getFile() 函数没有对 id 参数进行验证或规范化
  2. 依赖 path.join() 的规范化:虽然 path.join() 会规范化路径,但在特定情况下(如拼接前路径已包含 ..)仍可能允许路径遍历
  3. 未签名的 cookie:允许攻击者完全控制 session ID 的值
下载工具