PHP Conference Japan 2024

用户提交的数据

许多PHP程序中最大的弱点并非源于语言本身,而仅仅是代码编写时没有考虑到安全问题。因此,您应该始终花时间考虑给定代码片段的含义,以确定如果向其提交了意外变量可能造成的损害。

示例 #1 危险的变量使用

<?php
// 从用户的 home 目录中删除一个文件... 或者可能是
// 其他人的?
unlink ($evil_var);

// 记录他们的访问... 或者可能是 /etc/passwd 条目?
fwrite ($fp, $evil_var);

// 执行一些琐碎的事情.. 或者 rm -rf *?
system ($evil_var);
exec ($evil_var);

?>

您应该始终仔细检查您的代码,以确保从 Web 浏览器提交的任何变量都已正确检查,并自问以下问题

  • 此脚本只会影响预期的文件吗?
  • 可以对异常或不希望的数据进行操作吗?
  • 此脚本可以以意外的方式使用吗?
  • 这可以与其他脚本结合使用以产生负面影响吗?
  • 所有交易都会被充分记录吗?

通过在编写脚本时充分提出这些问题,而不是事后才提出,可以避免在需要提高安全性时进行不幸的重写。通过从一开始就秉持这种思维方式,虽然不能保证系统的安全性,但可以帮助提高安全性。

您可能还想考虑关闭 register_globals、magic_quotes 或其他可能让您对给定变量的有效性、来源或值感到困惑的便捷设置。在 error_reporting(E_ALL) 模式下使用 PHP 也可以帮助您警告在检查或初始化之前使用的变量(以便您可以防止对异常数据进行操作)。

添加注释

用户贡献的注释 2 条注释

79
Uli Kusterer
19 年前
我想在这里重复说明的是,哪些信息实际上来自用户。许多人认为 Cookie 由于是由 PHP 编写的,因此是安全的。但事实是它存储在用户的计算机上,由用户的浏览器传输,因此很容易被操纵。

因此,在这里再次提到这一点会很有帮助

URL 中的 CGI 参数、HTTP POST 数据和 Cookie 变量被视为“用户数据”,因此需要进行验证。会话数据和 SQL 数据库内容仅在来自不可信来源(如前面提到的那些)时才需要进行验证。

这不是新的内容,但我原本期望在该标题下看到这些信息,至少作为简短的摘要加上实际文档的链接。
6
Livingstone@stonyhills[dot]com
16 年前
确保您的表单是从您的页面提交的!也可以通过向查询字符串添加 &token 并使用 $_GET 对其与会话数据(或您喜欢的任何数组)进行检查来将其应用于 URL,这并不是说此字符串是随机生成的并存储的。如果您不想使用 $_SESSION,您可以构建自己的数组来存储生成的字符串,例如,您可以将其设为 $tokens = array(),并在您的 easysecure 类中将所有内容存储在该数组中!

<?php

class easysecure {

var
$curr_user;
var
$curr_permission;
var
$curr_task;
var
$validpermission;
var
$error;


function &
setVar( $name, $value=null ) {
if (!
is_null( $value )) {
$this->$name = $value;
}
return
$this->$name;
}

function
maketoken($formname, $id){

$token = md5(uniqid(rand(), true));

$_SESSION[$formname.$id] = $token;

return
$token;
}

function
checktoken($token, $formname, $id){
//print_r($_SESSION);
//echo ($token);
//如果我们没有有效的令牌,则返回无效;
if(!$token){
$this->setVar('validpermission', 0);
$this->setVar('error', '未找到令牌,检测到安全桥');
return
false;
}

//如果我们有一个有效的令牌,请检查它是否有效
$key = $_SESSION[$formname.$id];
if(
$key !== $token ){
$this->setVar('validpermission', 0);
$this->setVar('error', '无效令牌');
return
false;
}

if(
$this->validpermission !==1){
echo
'运行此脚本的权限无效';
return
false;
}else{
return
true;
}
}

}

?>

<?php $userid = *** //将其设置为任何您喜欢的 ID ?>
<form name="newform" action="index.php" method="post">
<input type="text" name="potentialeveilfield" value="" size 30 />
<input type="hidden" name="token" value="<?php echo maketoken(newform, $userid); //$userid 这里可以是用户个人资料 ID ?>" />
<input type="submit" />
</form>

现在,在处理表单时... 检查令牌的值

<?php

//嗯,您知道表单名称
if(!checktoken($_POST['token'], 'newform', $userid))
{
//失败
exit(); //或者任何最适合您的终止和通知方法。
//您也可以根据自己的方式设计类以获得更准确的失败(来自 var 的错误消息)
}

//您现在可以继续进行输入数据清理(验证)

?>
To Top