REQUEST_URI 返回的是包括後面數據串的地址,如 index.php?str=1234 PHP_SELF 是 index.php
--------------------------------------------------------------------------------
$_SERVER[’PHP_SELF’]在開發的時候常會用到,通常用來引用當前網頁地址,而且它是系統自動生成的全局變量,也會有什麼問題麼?讓咱們先看看下面的代碼吧:
<form action=」<?php echo $_SERVER[’PHP_SELF’]; ?>」> <input type=」submit」 name=」submit」 value=」submit」 /> </form>
這段代碼很是簡單,咱們想用$_SERVER[’PHP_SELF’]來讓網頁提交時提交到它本身,假設代碼文件名爲test.php,在執行的時候就必定會獲得咱們指望的地址麼?首先試試地址http://…/test.php,結果固然是沒有問題的啦,彆着急,你再訪問一下http://…/test.php/a=1,將會獲得以下客戶端代碼:
<form action=」/fwolf/temp/test.php/a=1″> <input type=」submit」 name=」submit」 value=」submit」 /> </form>
顯然,這已經超出了咱們的指望,web服務器竟然沒有產生諸如404之類的錯誤,頁面正常執行了,而且在生成的html代碼中竟然有用戶能夠輸入的部分,恐怖的地方就在這裏。別小看那個「a=1」,若是把它換成一段js代碼,就顯得更危險了,好比這麼調用:
http://…/test.php/%22%3E%3Cscript%3Ealert(’xss’)%3C/script%3E%3Cfoo
是否是看到了js的alert函數執行的效果?檢查一下生成的html源代碼找找緣由吧。
經過這種嵌入js代碼的方式,攻擊者能夠得到512~4k的代碼空間,甚至還能夠鏈接外部網站的js代碼或者經過image調用來假裝js代碼的方式,那樣js代碼的長度就不受限制了,而後經過js,他們能夠輕鬆的獲取用戶的cookie,或者更改當前頁面的任何內容,好比更改表單提交的目的地,更改顯示的內容(好比給一個連接地址增長一個onclick=…的屬性,這樣用戶點擊的時候就會執行攻擊者指定的代碼,甚至鏈接到並不是此連接地址自己的網站),甚至做出一個ajax效果來也不必定,總之,不要忽視js的威力。
那麼,再來看看這個漏洞產生的原理,首先test.php/….這種調用是web服務器容許的,不少cms系統,好比我之前用過的plog,好像也是採用這種方式,在服務器不支持rewrite的狀況下實現諸如http://… /index.php/archive/999這樣的固定網址的(我之前還覺得是對404錯誤頁下的手),因此帶「/」的地址沒法從web服務器上禁止。而後再看看php中對$_SERVER[’PHP_SELF’]的識別,他就是一個包含當前網址值的全局變量,天知道用戶會輸入什麼樣的網站,在上面的例子中是惡意的,但是在wikipedia這樣的網站上,卻又是能夠正常使用這種方式的地址的。因此,最終的結論要落在開發人員身上了,沒有很好的處理與用戶交互的數據。
從安全角度來說,在開發應用尤爲是web應用的時候,全部用戶提交的數據都是不安全的,這是基本原則,因此咱們纔不厭其煩的又是客戶端驗證又是服務端驗證。從上面說的這個安全漏洞來說,不安全的內容中又要增長「網址」一條了。要解決$_SERVER[’PHP_SELF’]的安全隱患,主要有如下2種方式:
一、htmlentities
用htmlentities($_SERVER[’PHP_SELF’])來替代簡單的$_SERVER[’PHP_SELF’],這樣即便網址中包含惡意代碼,也會被「轉換」爲用於顯示的html代碼,而不是被直接嵌入html代碼中執行,簡單一點說,就是「<」會變成「<」,變成無害的了。
二、REQUEST_URI
用$_SERVER[’REQUEST_URI’]來替代$_SERVER[’PHP_SELF’],在phpinfo()中能夠看到這兩個變量的區別:
_SERVER[」REQUEST_URI」] /fwolf/temp/test.php/%22%3E%3Cscript%3Ealert(’xss’)%3C/script%3E%3Cfoo _SERVER[」PHP_SELF」] /fwolf/temp/test.php/」>
$_SERVER[’REQUEST_URI’]會原封不動的反映網址自己,網址中若是有%3C,那麼你獲得的也將會是%3C,而$ _SERVER[’PHP_SELF’]會對網址進行一次urldecode操做,網址中的%3C將會變成字符「<」,因此就產生了漏洞。須要注意的是,在不少狀況下,瀏覽器會對用戶輸入要提交給web服務器的內容進行encode,而後服務器端程序會自動進行decode,獲得相應的原指,在咱們進行post或者get操做的時候都是這樣。
另外還有兩點須要指出,第一是這種寫法雖然沒有直接用到$_SERVER[’PHP_SELF’],但實際效果倒是同樣的,只是發生的時間錯後到了用戶提交以後的下一個頁面,因此,form的action仍是不要留空的好。第二點,除了PHP_SELF以外,其餘的$_SERVER變量也許也會有相似的漏洞,好比SCRIPT_URI, SCRIPT_URL, QUERY_STRING, PATH_INFO, PATH_TRANSLATED等等,在使用他們以前必定要先做htmlentities之類的php