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