C++ 中的路径清理

发布于 2024-07-24 23:47:43 字数 179 浏览 6 评论 0 原文

我正在编写一个类似 FTP 的小型只读服务器。 客户端说“给我那个文件”,然后我的服务器发送它。

是否有任何标准方法(库函数?!?)来确保请求的文件不是“../../../../../etc/passwd”或任何其他坏事? 如果我可以将所有查询限制到一个目录(及其子目录),那就太好了。

谢谢你!

I'm writing a small read-only FTP-like server. Client says "give me that file" and my server sends it.

Is there any standard way (a library function?!?) to make sure that the file requested is not "../../../../../etc/passwd" or any other bad thing? It would be great if I could limit all queries to a directory (and its subdirectories).

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

心的位置 2024-07-31 23:47:43

Chroot 可能是最好的方法,但您可以使用 realpath(3) 来确定给定文件名的规范路径。 从手册页:

 char *realpath(const char *file_name, char *resolved_name);

realpath() 函数解析文件名中的所有符号链接、额外的“/”字符以及对 /./ 和 /../ 的引用,并将生成的绝对路径名复制到解析名称引用的内存中。 solved_name 参数必须引用能够存储至少 PATH_MAX 个字符的缓冲区。

从那里您可以按照您喜欢的任何其他方式限制请求。

Chroot is probably the best way to go, but you can use realpath(3) to determine the canonical path to a given filename. From the man page:

 char *realpath(const char *file_name, char *resolved_name);

The realpath() function resolves all symbolic links, extra '/' characters, and references to /./ and /../ in filename, and copies the resulting absolute pathname into the memory referenced by resolved name. The resolved_name argument must refer to a buffer capable of storing at least PATH_MAX characters.

From there you can restrict the request in any additional way you like.

染柒℉ 2024-07-31 23:47:43

另请查看 chroot

Also take a look at chroot

燕归巢 2024-07-31 23:47:43

虽然这并不完美,但您可以在特定用户/组下运行 ftp 服务器,并且只向该用户/组授予某些目录的权限。 然而,这可能并不正是您正在寻找的。

您还可以有一个用户可以访问的目录白名单,以及他们尝试访问的任何其他目录,而您根本不允许(因此,基本上是构建您自己的权限)。

我个人更喜欢前者,因为操作系统已经为您完成了这项工作。

While this isn't perfect, you can run your ftp server under a specific user/group, and only permission certain directories to that user/group. This, however, may not be exactly what you're looking for.

You can also have a whitelist of directories users can go to, and any others they try to go to, you simply don't allow (thus, basically building your own permissioning).

I, personally, prefer the former, as the work is already done for you by the OS.

白首有我共你 2024-07-31 23:47:43

获取根 (/) 目录和服务目录(例如 /ftp/pub)的 inode。 对于他们请求的文件,请确保:

  1. 文件存在。
  2. 文件的父级(在文件路径上使用多个“/..”访问)在到达根目录 inode 之前先到达服务目录 inode。

您可以使用stat查找任何目录的inode。 将其放入一个函数中,并在提供文件之前调用它。

当然,使用具有适当权限的用户/组也可以。

Get the inode of the root (/) directory, and that of the serving directory (say /ftp/pub). For the files they request, make sure that:

  1. The file exists.
  2. The parents of the file (accessed using multiple "/.." on the file path) hit the serving directory inode before it hits the root directory inode.

You can use stat to find the inode of any directory. Put this in one function, and call it before serving the file.

Of course using a user/group with appropriate privilege will work as well.

新雨望断虹 2024-07-31 23:47:43

我不知道有哪个标准库可以实现这一点。

您可以尝试:

  1. 将运行服务器的unix用户的权限设置为仅对某个目录具有读/写权限。 (可能使用PAM、chroot 环境或使用标准unix 用户/组权限)

  2. 您可以设计程序,使其只接受绝对路径(在 unix 中,以“/”开头的路径)。 这样,您可以检查以确保它是有效路径 - 例如,禁止任何包含字符串“..”的路径

编辑:

来自 Peter:看起来有一个库函数,realpath() 这有助于解决上面的#2。

I don't know of a standard library that accomplishes this.

You could try:

  1. Set the permissions of the unix user who is running the server to only have read/write permissions to a certain directory. (maybe using PAM, a chrooted environment, or using standard unix user/group permissions)

  2. You could design your program so that it only accepts absolute paths (in unix, paths beginning with '/'). That way, you can check to make sure it is a valid path - for example, disallow any path which has the string ".."

edit:

From Peter: looks like there is a library function, realpath() which helps with #2 from above.

没企图 2024-07-31 23:47:43

在Windows中,我会做类似的事情(尽管仍然适用于任何操作系统):

  1. 用户请求文件
  2. 服务器查找文件
  3. 服务器检查path_to_file是否以“C:/SomeFolderWithFiles/”开头
  4. 完成事务

In Windows, I would do something like (still applies to any OS though):

  1. User requests file
  2. Server finds file
  3. Server checks if path_to_file starts with "C:/SomeFolderWithFiles/"
  4. Finish transaction
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文