PHP安全之register_globals


一、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();  
      
    ?>  

轉載:http://blog.csdn.net/alex_best/article/details/6076684


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM