通过表单提交发送 PHP 文件系统函数的变量
我试图找到一种安全的方法来执行以下操作:
- 用户将值输入 html 表单。
- 表格已提交。
- PHP 使用提交的值作为“scandir”函数的参数。
我的理论是 PHP 脚本中的包含逻辑禁止绝对路径并要求目录名称包含某个值。
我担心黑客可以使用我的表单提交他自己的值并访问敏感文件。
这是一个 JQuery 插件。 我不希望用户必须修改 PHP 文件。
下面的代码如何被黑客攻击?
<?php
$foo = $_POST["some_directory"];
//validate $foo
//make sure path to directory is relative
$foo_url_test = parse_url($foo);
if (isset($foo_url_test['scheme']) || isset($foo_url_test['host'])) {
$foo = NULL;
}
//make sure the directory name contains 'bar123'
$foo_name_test = preg_split('_[\\\\/]_', $foo);
$foo_name_test = end($foo_name_test);
$foo_name_test = strpos($foo_name_test,'bar123');
if ($foo_name_test === false) {
$foo = NULL;
}
//make sure the path does not contain '..'
$foo_dot_dot_test = strpos($foo,'..');
if ($foo_dot_dot_test == TRUE || $foo_dot_dot_test === 0) {
$foo = NULL;
}
//get files
$files_array = scandir($foo);
?>
I'm trying to find a secure way to do the following:
- Users enters value into html form.
- Form is submitted.
- PHP uses submitted value as the argument for the "scandir" function.
My theory is include logic in the php script that forbids absolute paths and requires the directory name to include a certain value.
My concern is that a hacker could use my form to submit his own value and access sensitive files.
This is for a JQuery plugin. I don't want users to have to modify the PHP file.
How could the below code be hacked?
<?php
$foo = $_POST["some_directory"];
//validate $foo
//make sure path to directory is relative
$foo_url_test = parse_url($foo);
if (isset($foo_url_test['scheme']) || isset($foo_url_test['host'])) {
$foo = NULL;
}
//make sure the directory name contains 'bar123'
$foo_name_test = preg_split('_[\\\\/]_', $foo);
$foo_name_test = end($foo_name_test);
$foo_name_test = strpos($foo_name_test,'bar123');
if ($foo_name_test === false) {
$foo = NULL;
}
//make sure the path does not contain '..'
$foo_dot_dot_test = strpos($foo,'..');
if ($foo_dot_dot_test == TRUE || $foo_dot_dot_test === 0) {
$foo = NULL;
}
//get files
$files_array = scandir($foo);
?>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可能想查看 realpath()。
...或类似的东西。
You might want to look at realpath().
...or something like that.
您可能需要进一步详细说明该脚本的用途以及它为何要读取任意目录。 如果没有这些知识,就很难评论这段代码的安全性,除非指出这是一件极其危险的事情,而且对可访问目录没有明确的限制。
就我而言,我永远不会在我的服务器上安装 PHP 脚本,该脚本允许远程攻击者指定要读取的目录,甚至能够查明特定文件或目录是否存在。
有一个强有力的论据要求用户编辑由 php 读取的配置文件,该文件允许服务器所有者将允许此脚本打开的一组目录列入白名单
OP 回复后更新
这里的问题是所有“ajax”请求都是由浏览器直接发出的。 这意味着网络服务器在发出 ajax 请求的 html 页面中设置的任何数据都可能被恶意用户覆盖。 任何人都可以随时使用任何参数发出您的 ajax 请求,除非您以其他方式确保其安全。
一旦您的数据离开服务器,您就无法再信任它。 确保此安全的最佳方法是在服务器端保留允许目录的白名单。 如果您收到对不在允许列表中的目录的请求(或者可能不在允许列表中某个目录下的子目录中),那么您将拒绝该请求并给出标准错误响应。
You probably need to elaborate further on the purpose of this script and why it wants to read arbitrary directories. Without this knowledge, it is difficult to comment on the security of this code, other than to point out it is an extremely dangerous thing to do, without clear limitations on accessible directories.
I, for one, would never install a PHP script to my server that allows a remote attacker to specify a directory to read - or even to be able to find out if particular files or directories even exist.
There is a strong argument for REQUIRING the user to edit a config file, read by the php, that allows the server owner to white-list a set of directories that are allowed to be opened by this script
Update after reply from OP
The problem you have here is that all "ajax" requests are made directly by and from the browser. This means that any data that the webserver sets in the html page that makes the ajax request can be overwritten by a malicious user. Your ajax request can be made by anyone at any time with any parameter, unless you secure it to do otherwise.
As soon as your data leaves your server, you can no longer trust it. The best way to make this secure is to hold a white-list of allowed directories on the server-side. If you receive a request for a directory that is not on the allowed list (or perhaps not in a subdirectory underneath something in the allowed list) then you reject the request and give a standard error response.
您的目录名称可以包含
..
元素,因此它们可以查看您打算限制它们的当前工作目录之外的内容。 不过,他们仍然只能查看按您的意愿命名的目录。FWIW,使用 parse_url() 来分析目录名是否是相对的确实很奇怪。 为什么不直接查找
$foo[0] == '/'
呢?(当然,这假定了 Unix 路径约定,但您的代码已经这样做了。)
Your directory name can contain
..
elements, so they can look outside the current working directory you're intended to limit them to. They'll still only be able to look at directories named as you intend, though.FWIW, using
parse_url()
to analyze whether a directory name is relative is really bizarre. Why don't you just look for$foo[0] == '/'
?(That assumes a Unix path convention, of course, but your code already does that.)