您现在的位置: 365建站网 > 365学习 > PHP安全 register_globals 值为on与off的讲解

PHP安全 register_globals 值为on与off的讲解

文章来源:365jz.com     点击数:141    更新时间:2017-12-11 18:28   参与评论

register_globals的值可以设置为:On或者Off,我们举一段代码来分别描述它们的不同。

代码:

 

<form name="frmTest" id="frmTest" action="URL">
<input type="text" name="user_name" id="user_name">
<input type="password" name="user_pass" id="user_pass">
<input type="submit" value="login">
</form>

 

当register_globals=Off的时候,下一个程序接收的时候应该用$_GET['user_name']和$_GET['user_pass']来接受传递过来的值。(注:当<form>的method属性为post的时候应该用$_POST['user_name']和$_POST['user_pass'])

当register_globals=On的时候,下一个程序可以直接使用$user_name和$user_pass来接受值。

顾名思义,register_globals的意思就是注册为全局变量,所以当On的时候,传递过来的值会被直接的注册为全局变量直接使用,而Off的时候,我们需要到特定的数组里去得到它。所以,碰到上边那些无法得到值的问题的朋友应该首先检查一下你的register_globals的设置和你获取值的方法是否匹配。(查看可以用PHPinfo()函数或者直接查看php.ini)

下面来看看这里有什么错误?

看看下面的这段PHP脚本,它用来在输入的用户名及口令正确时授权访问一个Web页面:

 

<?php
// 检查用户名及口令
if ($username == 'kevin' and $password == 'secret')
$authorized = true;
?>
<?php if (!$authorized): ?>
<!-- 未授权的用户将在这里给予提示 -->
<p>Please enter your username and password:</p>
<form action="<?=$PHP_SELF?>" method="POST">
<p>Username: <input type="text" name="username" /><br />
Password: <input type="password" name="password" /><br />
<input type="submit" /></p>
</form>
<?php else: ?>
<!-- 有安全要求的HTML内容 -->
<?php endif; ?>

 

上面的代码中存在的问题是你可以很容易地获得访问的权力,而不需要提供正确的用户名和口令。只在要你的浏览器的地址栏的最后添加?authorized=1。因为PHP会自动地为每一个提交的值创建一个变量 -- 不论是来自动一个提交的表单、URL查询字符串还是一个cookie -- 这会将$authorized设置为1,这样一个未授权的用户也可以突破安全限制。

一、register_globals = Off 和 register_globals = On的区别

register_globals是php.ini里的一个配置,这个配置影响到php如何接收传递过来的参数.

register_globals的值可以设置为:On或者Off,我们举一段代码来分别描述它们的不同。
 

<form action='' method='get'>
<input type='text' name='username' value='alex' >
<input type='submit' name='sub' value='sub'>
</form>
<?php
echo 'username::',$username;
echo '<br>sub::',$sub;
echo '<br>GET::';
print_r($_GET);

?>


当register_globals = On的时候,程序运行提交输出结果为:

    username::alex 
     
    sub::sub 
     
    array ( [username] => alex [sub] => sub )  
当register_globals = Off的时候,程序运行提交输出结果为:

    username:: 
     
    sub:: 
     
    array ( [username] => alex [sub] => sub )  
通过测试结果,显而易见:register_globals的意思就是注册为全局变量,所以当On的时候,传递过来的值会被直接的注册为全局变量直接使用,而Off的时候,我们需要到特定的数组里去得到它。

二、为什么推荐register_globals = Off?

1.PHP 4.2.0 版开始配置文件中 register_globals 的默认值从 on 改为 off 了,虽然你可以设置它为On,但是当你无法控制服务器的时候,你的代码的兼容性就成为一个大问题,所以,你最好从现在就开始用Off的风格开始编程。

2.当 register_globals 打开以后,各种变量都被注入代码,例如来自 HTML 表单的请求变量。再加上 PHP 在使用变量之前是无需进行初始化的,这就使得更容易写出不安全的代码。当打开时,人们使用变量时确实不知道变量是哪里来的,只能想当然。但是 register_globals 的关闭改变了这种代码内部变量和客户端发送的变量混杂在一起的糟糕情况。例子来源手册
 

    <?php 
     
    // 当用户合法的时候,赋值 
     
    $authorized = true 
     
     
    if (authenticated_user()) { 
     
    $authorized=true; 
     
    } 
     
     
    // 由于并没有事先把 $authorized 初始化为 false, 
     
    // 当 register_globals 打开时,可能通过GET auth.php?authorized=1 来定义该变量值 
     
    // 所以任何人都可以绕过身份验证 
     
    if ($authorized) {     
     
    include"/highly/sensitive/data.php"; 
     
    } 
     
    ?>  


当 register_globals = on 的时候,上面的代码就会有危险了。如果是 off,$authorized 就不能通过如 URL 请求等方式来改变,这样就好多了,尽管初始化变量是一个良好的编程习惯。比如说,如果在上面的代码执行之前加入 $authorized = false 的话,无论 register_globals 是 on 还是 off 都可以,因为用户状态被初始化为未经认证。

三、如果需要在一台关闭了 register_globals 的共享主机上运行一些旧式程序而该程序需要此选项打开时怎么办?

本例模拟 register_globals On。如果改变了配置文件中的 variables_order 选项,则考虑对 $superglobals 作出相应的改动。
 

    <?php// Emulate register_globals on 
     
    if (!ini_get('register_globals')) { 
     
    $superglobals= array($_SERVER,$_ENV,$_FILES,$_COOKIE,$_POST,$_GET); 
     
    if (isset($_SESSION)) { 
     
    array_unshift($superglobals,$_SESSION); 
     
    } 
     
    foreach ($superglobals as $superglobal) { 
     
    extract($superglobal,EXTR_SKIP);     
     
    } 
     
    } 
     
    ?> 


四、如果需要在一些打开了register_globals选项的主机上但想消除安全隐患,该怎么办?

本例模拟 register_globals Off。要记住此代码应在脚本最开头的地方调用。如果使用了会话机制,则在 session_start() 之后调用。

    <?php// Emulate register_globals off 
     
    functionun register_GLOBALS(){ 
     
    if (!ini_get('register_globals')) { 
     
    return;     
     
    } 
     
    // Might want to change this perhaps to a nicer error 
     
    if (isset($_REQUEST['GLOBALS']) || isset($_FILES['GLOBALS'])) { 
     
    die('GLOBALS overwrite attempt detected');     
     
    } 
     
    // Variables that shouldn't be unset     
     
    $noUnset= array('GLOBALS','_GET','_POST','_COOKIE','_REQUEST','_SERVER','_ENV','_FILES'); 
     
    $input=array_merge($_GET,$_POST,$_COOKIE,$_SERVER,$_ENV,$_FILES,isset($_SESSION) &&is_array($_SESSION) ?$_SESSION: array()); 
     
    foreach ($input as $k=>$v) { 
     
    if (!in_array($k,$noUnset) && isset($GLOBALS[$k])) { 
     
    unset($GLOBALS[$k]);         
     
    }     
     
    } 
     
    } 
     
     
    unregister_GLOBALS(); 
     
    ?>  

如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛


发表评论 (141人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码: 点击我更换图片
最新评论
------分隔线----------------------------