很簡單就可以實作破解,而且只要是登入系統都有可能有這類問題。
但也是很簡單就可以預防的。
我就嘗試了...幾個網站,目前是除了pixnet和天空,或是自行架設的wordpress沒有這個問題,其它都有。
- W BSP的加入好友
- R BSP的 刪除文章
- X BSP的刪除部落格
- .....
(此篇文章公開發布前,已先知會上述部落格請求修正)
程式範例
一般登入的實作,是用SESSION來判斷使用者是否登入。
$_SESSION['id']='girvan'
再查看SESSION裡面是否有值
那使用者要作任何的操作時,都要先判斷是否有登入,才能執行下一步,比如說發文... (先簡稱下面這個為「頁面A」)
--
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
if(empty($_SESSION['id'])) //必需要先登入 | |
die('Please Login First'); | |
save_post($_POST['content'],$_SESSION['id']); //可以進行儲存的動作 |
這段程式有什麼漏洞呢?
這個「頁面A」的執行的必要條件是...
- 已登入
- 傳進需要的參數 (通常是form,帶著某些POST的值)
但是有可能這個頁面,未必是使用者親自執行的。 使用者有可能是透過駭客的留言「連結」,連到惡意的頁面。 然後這個惡意的頁面,「幫」使用者送出必要的參數。 雖然駭客無法知道登入的SESSION是什麼,但是駭客知道所有的參數。 實際一點的例子就是,在使用者在無名小站中如果是登入的狀態下,只要跑到我的頁面,我就自動幫他post一個form回無名小站,該使用者就會將我加入好友。
解決方案1:
在系統中,寫了一個function --
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
//input可以是單一字串,或是array | |
function must_referer($src){ | |
$src_arr=Array(); | |
if(empty($_SERVER['HTTP_REFERER'])) //一定要有referer url | |
exit; | |
$src_arr=(is_array($src))?$src:Array($src); | |
foreach($src_arr as $url) | |
if(strpos($_SERVER['HTTP_REFERER'],$url)===0) //一定要match到,而且是第一個字元就要match到 | |
return; //有match到,就結束這個function | |
exit; //都沒有match到,將整支程式結束掉 | |
} |
然後預防方法就這麼做...
--
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
if(empty($_SESSION['id'])) //必需要先登入 | |
die('Please Login First'); | |
must_referer("http://admin.tools.sopili.net"); //來源一定要是從 admin.tools.sopili.net 操作 | |
save_post($_POST['content'],$_SESSION['id']); //可以進行儲存的動作 |
解決方案2:
這是pixnet的方法,它在每一個操作中,都加了hidden的sToken,只要sToken不正確就會出錯,儘管使用者不小心把referer關掉,也不會出問題。(不過使用者把referer關掉,也不能逛很多相簿的網站吧!)
結論
這是從雞蛋裡面挑骨頭,但這就是安全性的問題。如果在使用者登入的情況下,我可以輕易的將使用者騙到我的頁面中,再對使用者做些什麼事情。只要彎彎在登入的情況下,到我設計的頁面,她就會自動加我為好友!或者是刪除使用者的部落格!或是刪除使用者的所有文章。請各BSP先行修正,謝謝。