Php 核实一下?在外面的停车场,在机场前门,或者在乘客登机前?如果id被操纵为1'| | 1=1,可能会有人闯入。如果不需要使用递归,就不要这样做。它使调试变得困难,有时会产生不可预测的结果。我使用递归只是因为它似乎有逻辑意义。如果我想对照允许的状态列表检查用户

Php 核实一下?在外面的停车场,在机场前门,或者在乘客登机前?如果id被操纵为1'| | 1=1,可能会有人闯入。如果不需要使用递归,就不要这样做。它使调试变得困难,有时会产生不可预测的结果。我使用递归只是因为它似乎有逻辑意义。如果我想对照允许的状态列表检查用户,php,security,authorization,Php,Security,Authorization,核实一下?在外面的停车场,在机场前门,或者在乘客登机前?如果id被操纵为1'| | 1=1,可能会有人闯入。如果不需要使用递归,就不要这样做。它使调试变得困难,有时会产生不可预测的结果。我使用递归只是因为它似乎有逻辑意义。如果我想对照允许的状态列表检查用户的状态,那么让函数调用本身检查每个单独的状态,然后汇总结果并返回1(如果有)似乎是有意义的。在我看来,这似乎是递归的教科书用法。不,这是完全不必要的递归用法。您可以在单个函数调用中执行检查-只需将检查应用于$userStatus。如果我还希望能



核实一下?在外面的停车场,在机场前门,或者在乘客登机前?

如果id被操纵为1'| | 1=1,可能会有人闯入。如果不需要使用递归,就不要这样做。它使调试变得困难,有时会产生不可预测的结果。我使用递归只是因为它似乎有逻辑意义。如果我想对照允许的状态列表检查用户的状态,那么让函数调用本身检查每个单独的状态,然后汇总结果并返回1(如果有)似乎是有意义的。在我看来,这似乎是递归的教科书用法。不,这是完全不必要的递归用法。您可以在单个函数调用中执行检查-只需将检查应用于$userStatus。如果我还希望能够混合使用权限,该怎么办?假设我想允许任何具有2级或更高级别访问权限的人,以及任何具有创始成员身份的人?如果我在混合参数,我仍然需要通过逻辑对每个条目进行迭代,以对其应用适当的检查。如果不知何故将id操纵为1'| | 1=1,可能会有人闯入。如果不需要使用递归,请不要。它使调试变得困难,有时会产生不可预测的结果。我使用递归只是因为它似乎有逻辑意义。如果我想对照允许的状态列表检查用户的状态,那么让函数调用本身检查每个单独的状态,然后汇总结果并返回1(如果有)似乎是有意义的。在我看来,这似乎是递归的教科书用法。不,这是完全不必要的递归用法。您可以在单个函数调用中执行检查-只需将检查应用于$userStatus。如果我还希望能够混合使用权限,该怎么办?假设我想允许任何具有2级或更高级别访问权限的人,以及任何具有创始成员身份的人?如果我混合了参数,我仍然需要通过逻辑迭代每个条目,以对其应用适当的检查。如果没有改变$id的方法,人们将如何管理SQL注入?这样的注入变量仍然是不好的做法。使用参数绑定。这是为什么?显然,参数绑定阻止了SQL注入,但我不知道如何更改$id。您没有显示调用代码如何定义$user_id,因此必须假设它可能来自不受信任的源,即使它存储在您的数据库中,这意味着它可能被欺骗。我说过,除了假设的情况外,所有情况下$user\u id都是$\u SESSION['user']['user\u id'],在每次页面重新加载期间从数据库中更新。如果没有改变$id的方法,人们将如何管理SQL注入?这种注入变量的做法仍然很糟糕。使用参数绑定。这是为什么?显然,参数绑定阻止了SQL注入,但我不知道如何更改$id。您没有显示调用代码如何定义$user_id,因此必须假设它可能来自不受信任的源,即使它存储在您的数据库中,这意味着它可能会被欺骗。我说过,除了假设的情况外,所有情况下$user\u id都是$\u SESSION['user']['user\u id'],它在每次重新加载页面时都会从数据库中更新。请阅读代码和提示!1.授权$user\U id、$NEQUESSARYCLEAR和2$已从会话数据中提取用户\u id。。。唯一不清楚的是什么类型的会话数据和清除来自何处,如果清除是可变的,它是从$\u会话['user']['$user\u id']中提取的,每次加载页面时都会从数据库中刷新。是的,但是$user\u id是如何进入数据库的呢?它可能来自不可信的来源。仅仅因为它在您的数据库中并不意味着它是安全的。@DeathMagus为什么要在每次页面加载时重置$\u会话变量$_会话之所以存在,是因为它在整个会话中保持静态。@DeathMagus:我不是说你根本不能使用数据库。我的意思是,你不应该依赖数据免受黑客攻击。信任,但要验证。使用多层保护。如我在回答中所示,将$user_id强制为整数。请阅读代码和提示!1.授权$user\U id、$NEQUESSARYCLEAR和2$已从会话数据中提取用户\u id。。。唯一不清楚的是什么类型的会话数据和清除来自何处,如果清除是可变的,它是从$\u会话['user']['$user\u id']中提取的,每次加载页面时都会从数据库中刷新。是的,但是$user\u id是如何进入数据库的呢?它可能来自不可信的来源。仅仅因为它在您的数据库中并不意味着它是安全的。@DeathMagus为什么要在每次页面加载时重置$\u会话变量$_会话之所以存在,是因为它在整个会话中保持静态。@DeathMagus:我不是说你根本不能使用数据库。我的意思是,你不应该依赖数据免受黑客攻击。信任,但要验证。使用多层保护。类似于将$user\u id强制为in
这也是我的看法,但显然很多人不同意。知道他们为什么不同意吗?我做了一个有根据的猜测。他们不同意在影响$user_id var和$necessaryClearance的任何其他代码部分中显示这可能是可能的。这也是我的看法,但显然许多人不同意。知道他们为什么不同意吗?我做了一个有根据的猜测。他们不同意在影响$user_id var和$necessaryClearance的任何其他代码部分中显示它可能是可能的。感谢您的解释。我一定会调查PDO的。不过,简单地将$user_id强制转换为整数似乎没有帮助,因为如果有人可以更改该值,他们只需要发送一个具有管理员权限的值,而不是注入一个完全独立的SQL查询。另外,由于填充$_SESSION['user']['user\u id]的数据库字段将条目限制为整数值,因此类型转换不是多余的吗?如果您确定数据源是数据库中的整数列,并且可以执行代码检查以跟踪该会话数据的整个生命周期,这一点很好,确认它不能来自任何其他来源,那么你就可以有足够的安全保证。不过,我还是会保留int强制。这是一个廉价的操作,我更喜欢冗余的安全性。在您的示例中,SQL查询应该位于foreach之上,因为它将在每次迭代中返回相同的结果。另外,PDO::prepare更适合于使用不同参数执行多次的语句。这允许数据库服务器优化查询一次,而不是每次运行查询。我不确定这样做的影响,但我更喜欢像$sql='selectstatusfromsuserswereid='。$pdo->quote$user\u id$结果=$pdo->查询$sql$userData=$result->fetch;我可以在注释中编写多行代码吗?@JamesArmes根据PHP.net,PDF::prepare是首选方法,部分原因是它允许SQL server缓存通用查询表单。由于经常使用授权函数,我认为这可能非常有益。@DeathMagus只有在同一语句中多次运行查询时,这才是正确的。如果同一个查询要为同一个用户运行多次,那么查询缓存会带来好处,在5.1.17之前的MySQL中,它不用于准备语句。感谢您的解释。我一定会调查PDO的。不过,简单地将$user_id强制转换为整数似乎没有帮助,因为如果有人可以更改该值,他们只需要发送一个具有管理员权限的值,而不是注入一个完全独立的SQL查询。另外,由于填充$_SESSION['user']['user\u id]的数据库字段将条目限制为整数值,因此类型转换不是多余的吗?如果您确定数据源是数据库中的整数列,并且可以执行代码检查以跟踪该会话数据的整个生命周期,这一点很好,确认它不能来自任何其他来源,那么你就可以有足够的安全保证。不过,我还是会保留int强制。这是一个廉价的操作,我更喜欢冗余的安全性。在您的示例中,SQL查询应该位于foreach之上,因为它将在每次迭代中返回相同的结果。另外,PDO::prepare更适合于使用不同参数执行多次的语句。这允许数据库服务器优化查询一次,而不是每次运行查询。我不确定这样做的影响,但我更喜欢像$sql='selectstatusfromsuserswereid='。$pdo->quote$user\u id$结果=$pdo->查询$sql$userData=$result->fetch;我可以在注释中编写多行代码吗?@JamesArmes根据PHP.net,PDF::prepare是首选方法,部分原因是它允许SQL server缓存通用查询表单。由于经常使用授权函数,我认为这可能非常有益。@DeathMagus只有在同一语句中多次运行查询时,这才是正确的。如果同一个查询要为同一个用户运行多次,它将受益于查询缓存,在5.1.17之前的MySQL中,它不用于准备语句。
if(authorize($_SESSION['user']['user_id'], $necessaryClearance)){
    //Output restricted content
} else{
    //Inform user they are not authorized
}
//This function checks if the user is authorized to view the page
//It returns 1 if access is granted and a 0 if access is denied
function authorize($id, $clearance){
 //$clearance == array
    if (is_array($clearance)){
   //if yes Iterate array through Authorize($id, $clearance[])
  foreach($clearance as $userStatus){
   $tally += authorize ($id, $userStatus);

  }
   return $tally;
 //if no check if $clearenance is equal to a string
 }else if (is_string ($clearance)){
  $string = "SELECT status

  FROM users
      WHERE id = '$id'
      LIMIT 1";
  //If result returned.
  if($userData = mysql_fetch_array(Query($string))){
   if($clearance == $userData['status']){
    return 1;
   }else{ 
    return 0;
   }
  } else{
   return 0;
  }
  // if no check if $clearance is equal to a number  
 }else if(is_numeric($clearance)){
  $string = "SELECT level
      FROM users
      WHERE id = '$id'
      LIMIT 1";
  //If result returned
  if($userData = mysql_fetch_array(Query($string))){ 
   // if number is less than or equal to clearance level allow access
   if($userData['level'] <= $clearance){
    return 1;
   }else{ 
    return 0;
   }
  } else{
   return 0;
  }

 }else{
  //if nothing matches the page dies
  die('Authorization has failed.');
 }
}
function authorize($user_id, $clearance) {
  // coerce to integer to defend against SQL Injection
  $user_id = (int) $user_id;

  $sql = "SELECT status FROM users WHERE id = {$user_id}";
  $userData = mysql_fetch_array(Query($sql));

  $tally = 0;
  foreach ((array) $clearance as $userStatus) {
    if (is_numeric($userStatus)) {
      $tally += ($userData["level"] <= $userStatus);
    } else {
      $tally += ($userData["status"] == $userStatus);
    }
  }

  return $tally;
}
    $sql = "SELECT status FROM users WHERE id = ?";
    $stmt = $pdo->prepare($sql);
    $result = $stmt->execute(array($user_id));
    $userData = $stmt->fetch();