php表單提交程序的安全使用方法
一個(gè)學(xué)習(xí)過(guò)PHP的人很容易就能看懂上面的代碼,但為什么我要拿來(lái)分析,因?yàn)樵谖覍W(xué)習(xí)PHP期間,看了不少程序的代碼,發(fā)現(xiàn)有個(gè)很普遍的問(wèn)題,那就是大多數(shù)程序?qū)τ诮邮軄?lái)自于表單的數(shù)據(jù)做的檢查還是不夠嚴(yán)謹(jǐn),這恐怕是程序員思維問(wèn)題,因?yàn)檫@些安全措施都是很容易實(shí)現(xiàn)的。
對(duì)于一個(gè)簡(jiǎn)單的評(píng)論功能,我們假設(shè)它有兩個(gè)地方是需要用戶填寫的:評(píng)論人的姓名和評(píng)論內(nèi)容。那么,我們需要判斷的地方如下:
l 表單是否為空
l 表單長(zhǎng)度(該項(xiàng)和上面的項(xiàng)判斷稱為邏輯性判斷,凡事都要符合邏輯)
l 表單內(nèi)容(判斷記錄是否存在于數(shù)據(jù)庫(kù)內(nèi),防止重復(fù)提交)
l 隱藏變量的過(guò)濾(如果有的話,注意上面表單有一個(gè)隱藏變量type="hidden",這往往容易讓人忽略)
l 提交時(shí)間間隔(這個(gè)是最最容易被忽略的)
邏輯判斷很多人都做了,但這僅僅只是解決了程序的邏輯問(wèn)題,作為安全的程序,我們還要從安全的角度進(jìn)行判斷,一個(gè)沒(méi)有做過(guò)安全檢查的此類程序,最容易受到以下攻擊:
l 修改隱藏變量進(jìn)行非法提交(比如注入)
l 重復(fù)提交(對(duì)Web程序進(jìn)行DoS攻擊)
編者注:重復(fù)提交所形成的攻擊的確是個(gè)非常煩人的問(wèn)題,雖然這種方法沒(méi)有什么技術(shù)性可言,但卻會(huì)讓管理員傷透腦筋,因此很有必要在寫代碼時(shí)就加以防范。
修改隱藏變量通常是在本地構(gòu)造一個(gè)表單,然后指定隱藏變量,如果過(guò)濾不到位,直接構(gòu)造:
1' or 1=1 UNION Select * FROM any_table INTO OUTFILE 'c:/www/info.txt
然后提交,會(huì)有什么結(jié)果不用說(shuō)了吧?
如果采用POST提交表單后刷新會(huì)出現(xiàn)提示,然后確定就可以反復(fù)提交,這樣可以浪費(fèi)服務(wù)器的資源,如果量大的話站點(diǎn)速度可能會(huì)受少許影響,特別是數(shù)據(jù)量大的搜索引擎。這就是小小表單未做安全過(guò)濾的結(jié)果,相信任何站點(diǎn)管理員也不想看到吧?所以我們就要進(jìn)行防御。防御思路如下:
針對(duì)隱藏變量我們可以采用過(guò)濾,針對(duì)重復(fù)提交我們可以:
l 采用cookie/session進(jìn)行提交時(shí)間間隔的判斷;
l 提交前用strlen()函數(shù)判斷欲提交的標(biāo)題和內(nèi)容是否和數(shù)據(jù)庫(kù)里已有的一致;
l 完成提交后用Header("Location: url");跳轉(zhuǎn)到其他頁(yè)面
下面我們就對(duì)上面的savecomment.php的if代碼段進(jìn)行分析,關(guān)于針對(duì)修改變量攻擊的防御代碼大家可以看我在代碼上的注釋。對(duì)于采用cookie/session進(jìn)行提交時(shí)間間隔的判斷這兩種方法,我有以下看法:
Cookie:信息存在客戶端,利用工具可以修改、刪除使Cookie失效,因?yàn)樗沁B續(xù)發(fā)送,中間的間隔時(shí)間很短,來(lái)不急去刪除該Cookie的。但也不排除自己編段小程序來(lái)刪除Cookie。如果對(duì)Cookie不放心可以采用Session。
Session:信息存放在服務(wù)器,攻擊者不可能修改,但會(huì)占用服務(wù)器一丁點(diǎn)資源。我的服務(wù)器好,我就用Session,放心:)。
下面來(lái)看看分別用這兩種方式驗(yàn)證的代碼:
Cookie:
程序代碼
<?php
if (isset($_COOKIE['beforeid'])) {
error(“對(duì)不起,你兩次提交的時(shí)間間隔還不到2分鐘<br>”);
} else {
//先檢查相關(guān)Cookie是否存在,已存在則給出錯(cuò)誤提示,不存在則正確執(zhí)行的代碼段,比如插入Insert語(yǔ)句。執(zhí)行完畢以后設(shè)置一個(gè)Cookie,表示已經(jīng)提交過(guò),60*2表示2分鐘。
setcookie("beforeid",$blogid,time()+60*2,"/","",0);
succeed(“評(píng)論提交成功<br>”); }
?>
Session:
程序代碼
<?php
session_start();
if (session_is_registered("time") && time()-$_SESSION['time']<60*2) {
error(“對(duì)不起,你兩次提交的時(shí)間間隔還不到2分鐘<br>”);
//$time 前一次提交的時(shí)間
} else {
//先檢查相關(guān)Session是否存在,已存在則給出錯(cuò)誤提示,不存在則正確執(zhí)行的代碼段,比如插入Insert語(yǔ)句。執(zhí)行完畢以后設(shè)置一個(gè)Session,表示已經(jīng)提交過(guò),60*2表示2分鐘。
$time=time();
session_register("time");
succeed(“評(píng)論提交成功<br>”);
}
?>
這種時(shí)間間隔的方法可以用于各種表單,比如搜索、留言等,它可以有效地控制程序的有序運(yùn)行。
至于第三個(gè)思路是用Header("Location: url");跳轉(zhuǎn)頁(yè)面,我想既然加入了cookie/session驗(yàn)證就不必貿(mào)然跳轉(zhuǎn)了,畢竟大家還是想看看提交的相關(guān)信息的。
怎么樣?想不到小小的表單驗(yàn)證有這么大的學(xué)問(wèn)吧?簡(jiǎn)單幾行代碼就切斷讓攻擊者的路子,其實(shí)這些都很容易的,重要的是開(kāi)發(fā)人員驗(yàn)證的思路,我一個(gè)人只會(huì)加 cookie/session驗(yàn)證這個(gè)思路,結(jié)合Envymask的判斷長(zhǎng)度這條思路,我又掌握一點(diǎn)。其實(shí)開(kāi)發(fā)安全的程序,安全措施的思路很重要,即使掌握各種防御代碼,但如果考慮不嚴(yán)謹(jǐn),照樣有空子可鉆。
鄙人剛學(xué)PHP不到半個(gè)月。寫的代碼不夠規(guī)范、嚴(yán)謹(jǐn),在各位高手面前班門弄斧了。
后記:一個(gè)小小的程序,已經(jīng)折射出了一些普遍存在的安全問(wèn)題。在安全代碼的編寫過(guò)程中,僅僅注意以上問(wèn)題還是遠(yuǎn)遠(yuǎn)不夠的,不過(guò)很多重大腳本漏洞的出現(xiàn)卻都是因?yàn)檫@種小問(wèn)題引起的。平時(shí)可以看到,在一個(gè)腳本程序出現(xiàn)漏洞之后,往往一兩句代碼就可以將相關(guān)漏洞補(bǔ)得很嚴(yán)實(shí)了。腳本攻防是智者之間的較量,但是智者千慮,必有一失,所以相對(duì)于攻擊來(lái)說(shuō),防范要做到滴水不漏就顯得尤為困難。
- PHP魔術(shù)引號(hào)所帶來(lái)的安全問(wèn)題分析
- PHP開(kāi)發(fā)中常見(jiàn)的安全問(wèn)題詳解和解決方法(如Sql注入、CSRF、Xss、CC等)
- 基于PHP開(kāi)發(fā)中的安全防范知識(shí)詳解
- php安全開(kāi)發(fā) 添加隨機(jī)字符串驗(yàn)證,防止偽造跨站請(qǐng)求
- 簡(jiǎn)單的方法讓你的后臺(tái)登錄更加安全(php中加session驗(yàn)證)
- php中安全模式safe_mode配置教程
- PHP安全性漫談
- 理解php Hash函數(shù),增強(qiáng)密碼安全
- PHP防注入安全代碼
- php.ini 啟用disable_functions提高安全
- 淺談php安全性需要注意的幾點(diǎn)事項(xiàng)
相關(guān)文章
自寫的利用PDO對(duì)mysql數(shù)據(jù)庫(kù)增刪改查操作類
這篇文章主要給大家介紹了關(guān)于自寫的利用PDO對(duì)mysql數(shù)據(jù)庫(kù)的增刪改查操作類的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-02-02連接到txt文本的超鏈接,不直接打開(kāi)而是點(diǎn)擊后下載的處理方法
默認(rèn)情況下瀏覽器Mime類型設(shè)定中會(huì)直接打開(kāi)txt文本,但是如果想做到直接下載需要對(duì)Mime進(jìn)行設(shè)置。2009-07-07PHP 使用Echarts生成數(shù)據(jù)統(tǒng)計(jì)報(bào)表的實(shí)現(xiàn)代碼
這篇文章主要介紹了PHP 使用Echarts生成數(shù)據(jù)統(tǒng)計(jì)報(bào)表的實(shí)現(xiàn)代碼,需要的朋友可以參考下2018-01-01PHP實(shí)現(xiàn)取得HTTP請(qǐng)求的原文
這篇文章主要介紹了PHP實(shí)現(xiàn)取得HTTP請(qǐng)求的原文,需要的朋友可以參考下2014-08-08php獲取微信基礎(chǔ)接口憑證Access_token
這篇文章主要為大家詳細(xì)介紹了php獲取微信基礎(chǔ)接口憑證Access_token,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08利用discuz實(shí)現(xiàn)PHP大文件上傳應(yīng)用實(shí)例代碼
論壇的附件功能當(dāng)初設(shè)計(jì)的初衷并不是為了文件管理,由于服務(wù)器配置,php,網(wǎng)絡(luò)等多方面因素,使得通過(guò)論壇上傳文件并不是一個(gè)好方案。2008-11-11php使用文本統(tǒng)計(jì)訪問(wèn)量的方法
這篇文章主要介紹了php使用文本統(tǒng)計(jì)訪問(wèn)量的方法,涉及php文本文件讀寫與數(shù)值運(yùn)算的相關(guān)技巧,需要的朋友可以參考下2016-05-05php下獲取http狀態(tài)的實(shí)現(xiàn)代碼
在項(xiàng)目開(kāi)發(fā)中,有時(shí)我們需要知道遠(yuǎn)程的URL地址是否能訪問(wèn)正常,判斷其正常與否后進(jìn)行下一步的操作,那么在PHP中如何獲取遠(yuǎn)程HTTP的狀態(tài)呢2014-05-05