Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/238.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何避免PHP中的未链接安全风险?_Php_Ajax_Security_Unlink_Delete File - Fatal编程技术网

如何避免PHP中的未链接安全风险?

如何避免PHP中的未链接安全风险?,php,ajax,security,unlink,delete-file,Php,Ajax,Security,Unlink,Delete File,我正在使用与PHP和AJAX解除链接。我知道这样做很危险,因为每个人都可以删除任何文件。但是我需要使用AJAX,因为删除文件时无法重新加载页面 那么,我应该如何允许仅为拥有该文件的用户删除该文件? 如果您认为我在这里做错了什么,或者您想做的其他事情,并且您认为这会有用,请让我知道其他事情:) 我的PHP代码: 您需要以某种方式对用户进行身份验证 您的用户需要使用用户名和密码进行身份验证 PHP会话可以用来记忆,您应该使用服务器上的数据库表或文本文件来存储文件所有权信息 然后,在取消链接任何内容

我正在使用与
PHP
AJAX
解除链接。我知道这样做很危险,因为每个人都可以删除任何文件。但是我需要使用AJAX,因为删除文件时无法重新加载页面

那么,我应该如何允许仅为拥有该文件的用户删除该文件?

如果您认为我在这里做错了什么,或者您想做的其他事情,并且您认为这会有用,请让我知道其他事情:)

我的PHP代码:



您需要以某种方式对用户进行身份验证

您的用户需要使用用户名和密码进行身份验证

PHP会话可以用来记忆,您应该使用服务器上的数据库表或文本文件来存储文件所有权信息


然后,在取消链接任何内容之前,您的逻辑应该确保当前“已验证”的用户是文件的所有者。

将取消链接限制到包含照片的目录。也就是说,不允许在路径中使用
,或者在执行realpath()之后检查完整路径。否则,用户可以请求
删除\u photo.php?photo\u id=../../../../../etc/passwd
并中断系统。

在php中:

  • 确保$\u-GET['photo\u-id']和$\u-GET['thumbnail\u-id']不包含“.”
  • 还要确保在ID前面加上一个basepath
否则,用户可以删除任何文件


至于所有权,您必须将谁拥有哪个文件的信息存储在服务器端的某处(例如MySql数据库)。然后,在删除文件之前,您应该查阅此位置。

另一个建议:不要将文件存储在磁盘上,而是将它们放在数据库中。这将在站点+脚本和“用户数据”之间保持非常清晰的区别


(有人曾经告诉我,文件就是文件,数据库就是数据,这是不同的,但在我看来,文件无论如何都包含数据。mysql有一个完美的LONGBLOB类型来放入任何内容,你可以在同一数据行中的不同字段中存储元数据,如文件类型和文件名,这使事情保持干净和简单)

正如Wadih M.所说。您需要验证您的用户。然后您可以使用它来比较“图像的所有者”和“当前登录的用户”。这会给你所有你想要的安全感


正如我之前所说的,给变量命名,使它们听起来正确。当我在变量表中看到“id”时。作为一名程序员,我自动假设它是一个数值变量。

您可以通过使用非常简单的数据库替换(目录结构)来简化您的任务。将用户文件保存在用户目录中。因此,您可以随时检查特定用户是否具有删除权限。用用户名命名目录,或者用数字用户id命名更好

差不多

$photo_id = basename($_GET['photo_id'];)
$filename = $filebase.$_SESSION['user_id']."/".$photo_id;
if (file_exists($filename) unlink ($filename);

我们也遇到了同样的问题,并使用PHP的
ftp\u delete
函数解决了这个问题。如果您的意思是登录,那么用户就登录了。如果我不允许未登录的用户访问该文件,这会好一点,但登录的用户仍然可以删除彼此的文件。这就是为什么您需要将文件所有权存储在另一个表中,在取消链接任何内容之前,请确保“已验证”用户是该文件的所有者。这里唯一合理的答案是@请听上面的评论。这是唯一的解决办法。你走错了路。AJAX不是你的问题是的,这是一个合乎逻辑的答案,我的整个代码的问题是,在这个阶段,我不向数据库发送任何数据,但我想我能弄清楚,所以我会试试。@CIRK是的,一个完美的词-逻辑。如果不存储文件所有者的信息,则无法验证文件所有者。非常符合逻辑,不是吗?如果他们在不同的字符集中编码“..”,它可能会通过。我以前读过。@Wadih是的,但这是一个缺陷(我认为在Apache中),自那以后就被修复了。如果php是以root运行的,我想你会遇到更大的问题。事实上,因为PHP不是根目录,/etc/passwd的例子被夸大了,实际上不起作用。对于图像,我认为将它们存储在数据库中不是一个好主意(出于性能原因)。因为当显示它们时,您需要一个PHP脚本从数据库中读取。由于图像是独立的HTTP请求,这将导致需要建立多个到数据库的连接。仅供参考,Microsoft SharePoint 3.0会这样做(将文件存储在数据库中)。我不一定同意这个决定,因为我相信“文件系统”应该用来存储“文件”,而“数据库”应该用来存储表格数据。但这种设计模式在某些情况下是有意义的。请向我解释文件系统为什么不是数据库?从经验来看,在非外来卷上,性能肯定不是问题。数据库连接可以在请求之间保持。您必须权衡不利因素(性能)和有利因素(易维护性、备份、数据一致性、安全方面,如原始问题所述)。考虑一个mysql复制设置,其中涉及到的恐怖也复制文件@mvds我同意,通过文件系统维护文件二进制数据和文件元数据非常重要,尤其是在发生跨平台通信时(linux、windows等)。这两种技术都有各自的优点/缺点。@Wadih:幸运的是,我们并非所有人都有facebook或youtube那样的比例,因此不需要文件系统文件的唯一优点(性能)。留下了很多棘手的问题-请参阅我对@anraiki的评论,在php中,字符串大约为0字节,而不是底层的libc函数。ID不是数字:D它是
文件名
,前面有一些独特的东西,比如
efb03\u orange.png
。问题是,在本节中,我还没有向数据库发送任何内容。所以我不知道如何检查登录的用户是否是拥有f的用户
function deletePhoto(photo, thumbnail){

        var photos = encodeURIComponent(photo);
        var thumbnails = encodeURIComponent(thumbnail);

        if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
          xmlhttp=new XMLHttpRequest();
        } else {// code for IE6, IE5
          xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }

        xmlhttp.onreadystatechange=function() {
            if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                document.getElementById("media").innerHTML=xmlhttp.responseText;
            }
        }
        xmlhttp.open("GET", "http://192.168.2.104/images/users/delete_photo.php?photo_id="+photos+"&thumbnail_id="+thumbnails, true);
        xmlhttp.send();
    }
$photo_id = basename($_GET['photo_id'];)
$filename = $filebase.$_SESSION['user_id']."/".$photo_id;
if (file_exists($filename) unlink ($filename);