如何避免PHP中的UNLINK安全风险?

发布于 2024-09-13 17:55:59 字数 1445 浏览 7 评论 0原文

我将 UNLINK 与 PHP 和 AJAX 结合使用。我知道这种方式是非常危险的,因为每个人都可以删除任何文件。但我需要使用 AJAX 因为当我删除文件时我无法重新加载页面。

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

如果您认为我在这里做错了什么或您在其中做了其他事情,请也让我知道其他事情请注意,您认为它会很有用:)

我的 PHP 代码:


<?php

    $photo_id       = $_GET['photo_id'];
    $thumbnail_id   = $_GET['thumbnail_id'];    

    function deletePhotos($id){
        return unlink($id);
    }

    if(isset($photo_id)){
        deletePhotos($photo_id);
    }
    if(isset($thumbnail_id)){
        deletePhotos($thumbnail_id);
    }


 ?>

我的 AJAX 代码:


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();
    }

I'm using UNLINK with PHP and AJAX. I know that in this way is very dangerous, because everyone can delete any files. But I need to use AJAX because I can't reload the page when I delete the files.

So how should I do to allow to delete the file only for the user who owns it?

Please let me know other things too if you think I'm doing here something wrong or something else what you have in mind and you think that it will be useful : )

My PHP code:


<?php

    $photo_id       = $_GET['photo_id'];
    $thumbnail_id   = $_GET['thumbnail_id'];    

    function deletePhotos($id){
        return unlink($id);
    }

    if(isset($photo_id)){
        deletePhotos($photo_id);
    }
    if(isset($thumbnail_id)){
        deletePhotos($thumbnail_id);
    }


 ?>

My AJAX code:


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();
    }

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

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

发布评论

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

评论(7

独自唱情﹋歌 2024-09-20 17:55:59

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

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

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

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

You need to authenticate the user somehow.

Your user needs to be authenticated with a username and a password.

PHP session can be used to remember, and you should use a database table or a text file on the server to store file ownership information.

Then, before unlinking anything, your logic should make sure that the currently "authenticated" user is the owner of the file.

梦断已成空 2024-09-20 17:55:59

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

就像这样

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

you can simplify your task by using a very simple database substitution - a directory structure. keep user's files in user's directory. so, you can always check if particular user has rights to delete. Name a directory after user's name, or - much better - numeric user id

just something like

$photo_id = basename($_GET['photo_id'];)
$filename = $filebase.$_SESSION['user_id']."/".$photo_id;
if (file_exists($filename) unlink ($filename);
携余温的黄昏 2024-09-20 17:55:59

限制取消链接到带有照片的目录。也就是说,路径中不允许有 ..,或者在执行 realpath() 后检查完整路径。否则,用户可以请求 delete_photo.php?photo_id=../../../../etc/passwd 并破坏系统。

Limit the unlinking to the directory with the photos. That is, do not allow .. in the path, or check the full path after doing realpath(). Otherwise, the user can request delete_photo.php?photo_id=../../../../etc/passwd and break the system.

如果没有你 2024-09-20 17:55:59

在 PHP 中:

  • 确保 $_GET['photo_id'] 和 $_GET['thumbnail_id'] 不包含“../”
  • 还要确保在 ID 前面添加基本路径。

否则用户可以删除任何文件。

至于所有权,您必须将谁拥有哪个文件的信息存储在服务器端的某个位置(例如 MySql-DB)。那么您应该在删除文件之前查阅该位置。

In your PHP:

  • Make sure $_GET['photo_id'] and $_GET['thumbnail_id'] don't contain "../"
  • Also make sure you prepend a basepath to the ID.

Otherwise users can delete any file.

As for the ownership, you have to store the information who owns which file somewhere on the server side (for example a MySql-DB). Then you should consult this location before deleting the file.

遗心遗梦遗幸福 2024-09-20 17:55:59

正如 Wadih M. 所说。您需要验证您的用户。然后您可以使用它来将“图像的所有者”与“当前登录的用户”进行比较。这将为您提供您可能想要的所有安全保障。

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

As Wadih M. has said. You need to authenticate your user. Then you can use that to compare the "Owner of the Image" to the "User currently log in". This will give you all the security you may want.

As I said before, name the varaibles so that they sound right. When I see "id" in a varaiable. I automatically assume as a programmer that it is a numeric var.

喜爱皱眉﹌ 2024-09-20 17:55:59

遇到了同样的问题,并使用 PHP 的 ftp_delete 函数解决了这个问题

have had the same problem and got around it using PHP's ftp_delete function

南城旧梦 2024-09-20 17:55:59

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

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

A different suggestion: don't store files on disk, but put them in a database. This keeps a very clear distinction between your site+scripts and "user data".

(someone once told me that files were files, and databases were for data, and those are different, but as I see it, files contain data anyway. mysql has a perfect LONGBLOB type to put anything in, and you can store meta-data, such as file-type and filename, in separate fields in the same data row, which keeps things clean and simple)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文