You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在std::experimental::filesystem中限制用户仅在指定目录操作

如何防止路径遍历攻击,限制用户仅在指定目录创建文件

这是个典型的路径遍历攻击风险问题——用户通过输入包含../的相对路径,就能轻松突破你设定的工作目录限制,访问系统其他敏感目录。别担心,我们可以通过路径规范化和范围校验来彻底解决这个问题。

核心思路

要确保最终生成的文件路径完全被限制在你指定的工作目录之下,不能跳出这个范围。具体分两步:

  1. 把用户输入的路径转换为规范化的绝对路径,消除所有../、.和符号链接,得到真实的文件系统路径。
  2. 校验这个规范化路径是否以工作目录的绝对路径为前缀,以此判断是否越权。

代码实现示例

结合你使用的std::experimental::filesystem,可以这么写:

namespace fs = std::experimental::filesystem;

// 先把工作目录转换为绝对路径,避免相对路径带来的校验问题
fs::path working_path = fs::absolute(fs::path(getenv("HOME")) / "work");

// 处理用户传入的文件名
fs::path user_input_path = working_path / file_name;

// 使用weakly_canonical处理(适合创建新文件的场景,允许路径中存在未创建的子目录)
fs::path normalized_path = fs::weakly_canonical(user_input_path);

// 先确保工作目录存在,避免后续校验出错
if (!fs::is_directory(working_path)) {
    std::cerr << "Working directory does not exist!" << std::endl;
    return;
}

// 检查规范化后的路径是否以工作目录为前缀
if (normalized_path.string().compare(0, working_path.string().size(), working_path.string()) != 0) {
    // 路径越权,拒绝操作
    std::cerr << "Error: Access to paths outside the working directory is forbidden." << std::endl;
    return;
}

// 验证通过,安全创建文件
std::ofstream target_file(normalized_path);
if (target_file.is_open()) {
    // 写入内容逻辑
    target_file << "Content to write..." << std::endl;
    target_file.close();
} else {
    std::cerr << "Failed to create file!" << std::endl;
}

关键细节说明

  • fs::weakly_canonical vs fs::canonical:如果是创建新文件,推荐用weakly_canonical——它能处理路径中不存在的目录;而fs::canonical要求路径上的所有目录都必须存在,更适合校验已有文件的场景。
  • 绝对路径校验:一定要先把工作目录转为绝对路径,否则用相对路径做前缀对比会出现逻辑错误。
  • 永远不要信任用户输入:哪怕用户输入的看起来是普通文件名,也要经过规范化和校验,避免隐藏的路径遍历风险。

内容的提问来源于stack exchange,提问作者Reudi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:00:24