Php 关于验证的基本知识

Php 关于验证的基本知识,php,database,security,web-applications,authorization,Php,Database,Security,Web Applications,Authorization,当然,在web应用程序中,在许多情况下,我们将支持CRUD(创建、检索、更新、删除) 基本程序员将执行以下操作(无需验证): 显示的房间id仅适用于属于用户/客户的房间。 第一个身份验证仅使用用户和密码。这是一个标准 但我认为我们不应该信任用户。坏用户可能会猜到不属于他的房间id。如delete?room_id=199 我问我的程序员朋友,他们甚至从来没有想过这个问题 为了防止这种情况,我有一个基本的解决方案,就是始终传递任何相关对象的用户id。任何操作之前的此类查询是属于用户的房间id。 如果

当然,在web应用程序中,在许多情况下,我们将支持CRUD(创建、检索、更新、删除)

基本程序员将执行以下操作(无需验证):

显示的房间id仅适用于属于用户/客户的房间。 第一个身份验证仅使用用户和密码。这是一个标准

但我认为我们不应该信任用户。坏用户可能会猜到不属于他的房间id。如
delete?room_id=199

我问我的程序员朋友,他们甚至从来没有想过这个问题

为了防止这种情况,我有一个基本的解决方案,就是始终传递任何相关对象的用户id。任何操作
之前的此类查询是属于用户的房间id
。 如果这是唯一的解决方案,那么我必须修改我已经编写的所有查询

问题是,对于这个基本问题,有什么好的或更好的解决方案吗


谢谢

你的方法很好。你的程序员朋友们没有考虑过这一点,这真的不让我感到惊讶;不幸的是,安全性似乎是大多数程序员最不关心的事情

在一个好的系统中,您将对几乎执行的每个操作执行授权检查,以查看此特定用户是否有权执行该操作。在整个应用程序中构建此签入通常是一种很好的做法,即使是对于那些您通常并不关心它们是否被授权的事情:有一天您可能会被授权

在您的场景中,该操作可能是检索房间、更新房间甚至删除房间

为了帮助解决问题,我有一些建议:

  • 如果可能的话,使房间id不可猜测。假定您已经使用int作为主键,最简单的方法是在客户端浏览器和应用程序之间传递时对其进行加密/解密

  • 确保在浏览器端,您没有传递用户id,而是从会话或通过其他机制获取用户id。关键是你不想信任用户将id传递给你

  • 任何不是GET的操作都可以使用HTTP POST来执行。换句话说,您根本不应该将ID放在查询字符串中,而是作为post数据


  • 假设他登录时您已经在会话中注册了userid:session_register(“userid”)

    然后,您可以这样做来检查登录的用户是否拥有该房间(正如您所说的,您有一个同时包含roomid和userid的数据库)

    更改“表”(数据库中的哪个表同时包含这两个信息)、“用户id”(该表中的用户id列名)和“房间”(该表中的房间id列名)

    编辑:
    此外,如果您的房间ID可能包含任何字符,请删除intval();从$room开始,对它进行真正的转义,如果房间ID只是数字,不要更改它

    永远不要相信客户传递给你的任何东西。必须在服务器端验证每个请求,并检查是否允许登录用户执行该操作

    插入或查看时,必须对每个文本输入进行消毒。后者有更大的遗忘机会,因此提供了一个学习的领域。我建议对模板使用隐式清理


    还应尽量避免对批评操作使用GET方法。攻击者总是可以强制用户访问URL(iframe,向其发送缩短的链接)。您还应该在删除表单中添加特殊生成的令牌,以防止出现此问题。

    @Art:how$\u POST如何解决此问题?基本问题是找到检查对象是否属于用户的最佳方法。这不仅是一个对象,而且可能是一个对象。如房间、地址、衬衫等您是否有包含用户id和房间id的数据库,和@Art Planteur,用户也可以发布任何数据,它只是在一个隐藏字段中。我的评论是关于如果一个坏用户试图修改GET,它可能会产生错误。波斯特可以解决这个问题。根据您上面的回答,您需要一个请求来检查房间id是否存在用户id。您的数据库结构如何?向上投票,因为您和您的同事中只有一位关心安全问题。您好,感谢您的回答和示例。从理论上和实践上来说,你的答案和我的一样。我在第一个问题中已经提到了这一点,即在执行任何操作之前检查任何对象是否属于当前用户。这意味着我要修改所有的查询。要在执行此示例中的任何操作之前添加检查,对吗?不客气,是的,您需要在我键入的//用户拥有此房间的位置添加您的操作,并在//中添加一个警报,以警告用户他不拥有此房间,因为用户ID已经是查询条件的一部分,
    $found=$\u SESSION['userid']
    如果找到记录,则始终为真。太好了,谢谢您的推荐。但我认为加密和解密id会使应用程序变得更慢。@Ahmad,应用程序不会因为几个百科全书而变得更慢,同时使用加密和检查数据库比只检查数据库要好database@Ahmad:解密/加密id所花费的处理时间微不足道,以至于您不会注意到它。
    delete?room_id=12
    update?room_id=13
    
    $connect = mysql_connect("$server", "$dbuser", "$dbpassword")
        OR die(mysql_error());
    
    $room = intval($_GET['room_id']);
    $user = mysql_real_escape_string($_SESSION['userid']);
    
    mysql_select_db("$databasename", $connect);
    $select = mysql_query("SELECT userid AS uid FROM table WHERE userid='$user' AND room='$room'");
    $fetch = mysql_fetch_assoc($select); 
    $found = $fetch['uid']; 
    
    if ($found == $_SESSION['userid']){
    
    // User owns this room let him delete
    
    } else {
    
    // FAIL, This user does not own this room
    
    }