直播中
1.關(guān)于交互式動(dòng)態(tài)網(wǎng)頁(yè)可能存在的問(wèn)題
1.1 form類型的交互
1.1.1 概念介紹
在我們和瀏覽者進(jìn)行交互時(shí),最常用到的就是form(post/get/put方法),雖然非常方便,但是很多問(wèn)題也是因他而起。
form表單中input標(biāo)志
用來(lái)接受用戶輸入的信息,例如:用戶名、密碼、email等。如果你沒(méi)有對(duì)用戶輸入進(jìn)行很好的檢查的話,一個(gè)惡意的用戶
會(huì)屏蔽掉一些安全機(jī)
制,繞過(guò)安全認(rèn)證。例如,輸入標(biāo)準(zhǔn)的HTML語(yǔ)句或者javascript語(yǔ)句會(huì)改變輸出結(jié)果 ,在輸入框中打入標(biāo)準(zhǔn)的HTML語(yǔ)句會(huì)
得到什么樣的結(jié)果呢?比如一個(gè)留言本,我們留言內(nèi)容中打入:<font size=10>你好!</font> 如果你的程序中沒(méi)有屏
蔽html語(yǔ)句,那么就會(huì)改變"你好"字體的
大小。在留言本中改變字體大小和貼圖有時(shí)并不是什么壞事,反而可以使留言本生動(dòng)。但是如果在輸入框中寫(xiě)個(gè)
javascript 的死循環(huán),比如:
<a herf="http://someurl" onMouseover="while(1) {window.close('/')}">第一萬(wàn)個(gè)驚心動(dòng)魄</a> 那么其他查看該留言
的客人只要移
動(dòng)鼠標(biāo)到"第一萬(wàn)個(gè)驚心動(dòng)魄",上就會(huì)使用戶的瀏覽器因死循環(huán)而死掉。
1.1.2 防范要點(diǎn)
(1)對(duì)特殊字符進(jìn)行過(guò)濾
([\&;\`'\\\|"*?~<>^\(\)\[\]\{\}\$\n\r])/\\$1/g;),這個(gè)是最基本的,在很多地方也已經(jīng)不只一次提到過(guò)
<script language="vbscript">
sub uBotton_onclick
if form1.uUserName.value=""then
msgbox"您的姓名不能為空!",0+32,"哦!還不行"
form1.uUserName.focus
exit sub
end if
if form1.uPassword.value=""then
msgbox"您的密碼不能為空!",0+32,"哦!還不行"
form1.uPassword.focus
exit sub
end if
if form1.uUserName.value=""then
msgbox"您的姓名不能為空!",0+32,"哦!還不行"
form1.uUserName.focus
exit sub
end if
form1.submit
end sub
</script>
function isEmpty(objname)
{
var str = document.inputform[objname].value
var tmpstr = str.replace([\&;\`'\\\|"*?~<>^\(\)\[\]\{\}\$\n\r])/\\$1/g;,"")
var tmpstr = tmpstr.replace([\&;\`'\\\|"*?~<>^\(\)\[\]\{\}\$\n\r])/\\$1/g;,"")
return (tmpstr.length==0)
}
function check()
{
tf=document.inputform
errors=""
if (isEmpty("username")) errors += "用戶名不能為空。\n";
if (isEmpty("password")) errors += "密碼不能為空!\n"
if (errors!="")
alert(errors);
return (errors=="")
}
(2) 對(duì)輸入的字符長(zhǎng)度進(jìn)行限制
(3) 進(jìn)行盡可能多的錯(cuò)誤出理和錯(cuò)誤陷阱
(4) 盡可能多的使用以下這些標(biāo)志,減少用戶輸入的機(jī)會(huì)
<input type="checkbox" name="checkbox" value="checkbox">
<select name="select"> </select>
<input type="radio" name="radiobutton" value="radiobutton">
1.2 post/get類型的交互
1.2.1 概念介紹
這種類型的問(wèn)題主要是瀏覽者可以通過(guò)瀏覽器的地址欄對(duì)腳本頁(yè)通過(guò)添加參數(shù)來(lái)和服務(wù)器進(jìn)行交互,這些參數(shù)已經(jīng)繞過(guò)放
在客戶端提交頁(yè)的輸入檢
查了,還有就是可以通過(guò)地址欄輸入較長(zhǎng)的參數(shù)或惡意編造的代碼造成服務(wù)器異常運(yùn)算錯(cuò)誤,導(dǎo)致服務(wù)器宕機(jī)或緩沖區(qū)溢
出。
1.2.2 防范要點(diǎn)
(1) 盡量不要讓瀏覽者了解到你的運(yùn)算提交頁(yè)
(2) 不允許地址欄提交參數(shù)
例如ASP程序中的request.serverVariables(QUERY_STRING)檢測(cè)是否有參數(shù),如果有則使用response.redirect()強(qiáng)制返回
指定頁(yè),可以
是首頁(yè),或者你自己做的警告頁(yè)。
(3) 腳本頁(yè)間傳遞參數(shù)不要再瀏覽器欄顯示,盡可能少的讓瀏覽者了解你的程序規(guī)則、參數(shù)等
例如ASP中的Request.form和Request.QueryString這兩個(gè)數(shù)據(jù)集合分別使用的是post和get方法,我們盡量不要是用
Request.QueryString這個(gè)數(shù)據(jù)集合,盡可能少的讓瀏覽者有和你交互的機(jī)會(huì),
2. 安全認(rèn)證的問(wèn)題
2.1 需要安全認(rèn)證密碼認(rèn)證的可能存在的問(wèn)題
2.1.1 概念介紹
現(xiàn)在流行的CGI應(yīng)用程序傾向于收集信用卡信息。數(shù)據(jù)收集是CGI 應(yīng)用程序的一個(gè)簡(jiǎn)單的任務(wù),但是敏感信息的
收集需要一個(gè)將信息從瀏覽器傳送給服務(wù)器和CGI程序的安全途徑。
舉個(gè)例子,假設(shè)我要通過(guò)Internet來(lái)銷售書(shū)。我可能在瀏覽器上建立一個(gè)表單,允許要購(gòu)書(shū)的顧客通過(guò)表單提交它的個(gè)人
信息和信用卡號(hào)碼。受
到這些信息后,我會(huì)將它們存儲(chǔ)到我的計(jì)算機(jī)作為商業(yè)記錄。
如果有人侵入我的商業(yè)計(jì)算機(jī),那么他可能會(huì)訪問(wèn)存放顧客信息和信用卡號(hào)碼的機(jī)密數(shù)據(jù)。為了避免這種情況,我會(huì)審查
我的計(jì)算機(jī)配置安全了
,并確定用來(lái)接受表單的CGI腳本不會(huì)被惡意的操縱。換句話說(shuō),我,作為計(jì)算機(jī)的系統(tǒng)管理員和CGI程序員,要盡力控制
住第一個(gè)問(wèn)題:防止
信息直接從我的計(jì)算機(jī)中被竊取。
然而,怎樣防止當(dāng)信息由客戶端發(fā)往服務(wù)器過(guò)程中有人中途竊取呢?記住信息怎樣由Web服務(wù)器傳送到CGI程序了嗎?信息
通過(guò)網(wǎng)絡(luò)由瀏覽器先
傳送到服務(wù)器,然后服務(wù)器將信息傳送給CGI程序。這些信息可能在由客戶機(jī)傳送到服務(wù)器時(shí)被中途竊取(如圖2)。注意,
為了保護(hù)信息使其不會(huì)
被中途竊取,必須在客戶和服務(wù)器之間進(jìn)行加密。當(dāng)然,如果你的客戶機(jī)不能識(shí)別的話,你不能執(zhí)行特定CGI的加密。
由于Web處理的特點(diǎn),使用你獨(dú)有的單獨(dú)通過(guò)CGI程序?qū)崿F(xiàn)的安全處理協(xié)議的唯一途徑是:在表單信息通過(guò)瀏覽器傳送到服務(wù)
器之前將其加密。
這個(gè)方案如。
之前,發(fā)展你自己的安全處理協(xié)議幾乎是不可能的。感謝Java這樣的語(yǔ)言,最近在客戶端處理所作的創(chuàng)新,使得這個(gè)發(fā)展變
成可能。 方法是產(chǎn)生
一個(gè)標(biāo)準(zhǔn)HTML格式擴(kuò)展的Java接口。當(dāng)Java的提交按鈕被選擇時(shí),Java Applet會(huì)在利用標(biāo)準(zhǔn)的POST HTTP請(qǐng)求將它發(fā)送到
Web服務(wù)器前先
將值加密。
使用Java作為客戶機(jī)來(lái)發(fā)送和接收加密的數(shù)據(jù)將允許你使用自己定制的加密方案,而不需要一個(gè)昂貴的商業(yè)服務(wù)器。
因此,在網(wǎng)絡(luò)上安全保密地傳送數(shù)據(jù)信息需要調(diào)整瀏覽器和服務(wù)器之間的通信路徑,有一些是不能僅僅靠CGI就能夠控制
的。目前有兩種加密客
戶機(jī)/服務(wù)器信息處理的建議:SSL(Secure Sockets Layer)和SHTTP(Secure HTTP),分別由Netscape和EIT(Enterprise
Integrations
Technology)提議。關(guān)于這點(diǎn),目前還不清楚哪一個(gè)將成為標(biāo)準(zhǔn);很多公司在他們的服務(wù)器中兩種都采用了。因此,知道如
何在這兩者中編寫(xiě)
CGI程序是很有用的。
SSL是一個(gè)協(xié)議獨(dú)立的加密方案,在網(wǎng)絡(luò)信息包的應(yīng)用層和傳輸層之間提供了安全的通道(參照?qǐng)D5)。簡(jiǎn)單說(shuō)來(lái),就是HTML
或CGI經(jīng)過(guò)了幕后的
服務(wù)器進(jìn)行了加密處理,然而對(duì)HTML和CGI的作者來(lái)說(shuō)是透明的。
因?yàn)榭蛻舳撕头?wù)器端網(wǎng)絡(luò)程序處理加密過(guò)程,幾乎你的所有的CGI腳本不需要進(jìn)行安全事務(wù)的修正。有一個(gè)顯著的例外。
一個(gè)nph(no-parse-
header)的CGI程序繞過(guò)服務(wù)器而直接與客戶端進(jìn)行通信。因此,nph的CGI腳本不會(huì)經(jīng)過(guò)加密處理,因?yàn)樾畔⑽吹玫郊用堋?BR>受此影響的一個(gè)值得
注意的CGI應(yīng)用程序是Netscape服務(wù)器推動(dòng)的動(dòng)態(tài)實(shí)現(xiàn)(Netscape server-push animations)。我懷疑這是主要應(yīng)該值得注
意的,然而,更
有可能因?yàn)橐踩膫鬏斆舾行畔⒍鵂奚?yè)面中的動(dòng)畫(huà)。
SHTTP采用一種和SSL不同的方法。它通過(guò)擴(kuò)展HTTP協(xié)議(應(yīng)用層)來(lái)運(yùn)作,優(yōu)于一個(gè)較低層。因此,盡管SSL可以應(yīng)用于所有
的網(wǎng)絡(luò)服務(wù),然而
SHTTP是一個(gè)特定的Web協(xié)議。
另外,還有其它的優(yōu)點(diǎn)。作為HTTP的擴(kuò)展集,SHTTP全兼容于HTTP和SHTTP的瀏覽器和服務(wù)器。為了使用SSL,你必須有一個(gè)
支持SSL的瀏覽
器和服務(wù)器。另外,SHTTP是一個(gè)更靈活的協(xié)議。例如,這個(gè)服務(wù)器可以指定首選的加密方案。
SHTTP處理依賴于附加的HTTP頭。因此,如果你想讓你的CGI程序采用SHTTP的加密處理,你需要包含適當(dāng)?shù)念^。例如,替換
簡(jiǎn)單返回HTTP頭
。
Content-type:text/html
當(dāng)一個(gè)SHTTP服務(wù)器從CGI應(yīng)用程序中收到這個(gè)信息,它會(huì)知道在將其發(fā)送到瀏覽器之前將信息加密。一個(gè)非SHTTP的瀏覽器
將忽略附加的頭。
關(guān)于使用SHTTP的更多的信息,請(qǐng)參照SHTTP的說(shuō)明書(shū):
http://www.commerce.net/information/standards/drafts/shttp.txt
2.1.3 腳本解析
下面是我以前寫(xiě)的一段asp腳本,做了一些修改,把他貼出來(lái),讓大家看看我加入了設(shè)置,那里做的不夠好。我在這里就不
多說(shuō)了,有興趣可以到
我的論壇來(lái)大家討論。
<!--#include file="conn.asp"-->
<%
dim errmsg
if request.form("username")="" then
ErrMsg="用戶名不能為空"
foundError=True
else
UserName=request.form("UserName")
end if
if request.form("password")="" then
ErrMsg="密碼不能為空"
foundError=True
else
PassWord=request.form("PassWord")
end if
if FoundError=true then
showAnnounce(ErrMsg)
else
set rstmp=server.createobject("adodb.recordset")
if Request.ServerVariables("REQUEST_METHOD") = "POST" then
rstmp.open "Select * from User Where userName='" & UserName & "'",conn,3,3
if rstmp.bof then
session.contents("UserName")=UserName
rstmp.addnew
rstmp("username")=username
rstmp("userpassword")=password
rstmp("logins")=1
rstmp("online")=1
rstmp.update
response.redirect("index.asp")
elseif PassWord<>rstmp("userpassword") then
ErrMsg="密碼錯(cuò)啦"
foundError=True
showAnnounce(ErrMsg)
else
session.contents("UserName")=UserName
rstmp("logins")=rstmp("logins")+1
rstmp("online")=1
rstmp.update
rstmp.close
Set rstmp=nothing
response.redirect("index.asp")
end if
else
if session.contents("UserName")<>"" then
rstmp.open "Select * from User Where userName='"&session.contents("UserName")&"'",conn,3,3
rstmp("logins")=rstmp("logins")+1
rstmp("online")=1
rstmp.update
rstmp.close
Set rstmp=nothing
conn.close
set conn=nothing
response.redirect("index.asp")
end if
end if
end if
%>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="forum.css">
</head>
<body>
<%
function showAnnounce(ErrMsg)
on error resume next
response.write "<p align=center><font color='red'><strong><Big>哈哈</big></strong></font><BR><font
color='#0000FF'>"+ErrMsg+"</font><BR>"+chr(13)+chr(10)
%>
<tr>
<td width="100%">
<p align="center"><br>
<form action="login.asp" method="post">
輸入<INPUT name=username size=8 class='smallInput'>
<BR>哈哈<INPUT name=password size=8 class='smallInput' type=password>
</td>
</tr>
<tr>
<td width="100%">
<p align="center"><br>
<INPUT type="submit" name="B12" class='buttonface' value=μ???>
<font color="#FF0000"><br> <br>
*</font>錯(cuò)了
</td> </form>
</tr>
<%
end function
%>
###---checklogin.asp
<%
dim adname
dim passwd
adname=Request.Form("adname")
passwd=Request.Form("passwd")
if adname="" then
response.redirect "login.asp"
end if
if passwd="" then
response.redirect "login.asp"
end if
if adname="focus-admin" and passwd="1" then
response.redirect "manage.asp"
else
response.redirect "login.asp"
end if
%>
###---checklogin.asp----end
###---manage.asp
<%
dim where
dim where1
dim refererURL
dim refererURL2
dim refererURL3
refererURL=phyURL&"login.as"
refererURL2=phyURL&"edit.asp"
refererURL3=phyURL&"manage.a"
refererURL4=phyURL&"savearti"
where=Request.ServerVariables("HTTP_REFERER")
where=left(where,(len(phyURL)+8))
if where<>refererURL and where<> refererURL2 and where<>refererURL3 and where<>refererURL4 then
Response.Redirect "login.asp"
end if
const MaxPerPage=20
dim totalPut
dim CurrentPage
dim TotalPages
dim i,j
if not isempty(request("page")) then
currentPage=cint(request("page"))
else
currentPage=1
end if
%>
###---manage.asp-----end
2.2 cookie的問(wèn)題
2.2.1 概念介紹
按照Netscape官方文檔中的定義,Cookie是在HTTP協(xié)議下,服務(wù)器或腳本可以維護(hù)客戶工作站上信息的一種方式。Cookie
是由Web服務(wù)器保
存在用戶瀏覽器上的小廣西文件,它可以包含有關(guān)用戶的信息(如身份識(shí)別號(hào)碼、密碼、用戶在Web站點(diǎn)購(gòu)物的方式或用戶
訪問(wèn)該站點(diǎn)的次數(shù))
。無(wú)論何時(shí)用戶鏈接到服務(wù)器,Web站點(diǎn)都可以訪問(wèn)Cookie信息。
通俗地講,瀏覽器用一個(gè)或多個(gè)限定的文件來(lái)支持Cookie。這些文件在使用Windows操作系統(tǒng)的機(jī)器上叫做Cookie文件,在
Macintosh機(jī)器上
叫做magic Cookie 文件,這些文件被網(wǎng)站用來(lái)在上面存儲(chǔ)Cookie數(shù)據(jù)。網(wǎng)站可以在這些Cookie文件中插入信息,這樣對(duì)有
些網(wǎng)絡(luò)用戶就有些
副作用。有些用戶認(rèn)為這造成了對(duì)個(gè)人隱私的侵犯,更糟的是,有些人認(rèn)為Cookie是對(duì)個(gè)人空間的侵占,而且會(huì)對(duì)用戶的
計(jì)算機(jī)帶來(lái)安全性的危
害。
目前有些Cookie是臨時(shí)的,另一些則是持續(xù)的。臨時(shí)的Cookie只在瀏覽器上保存一段規(guī)定的時(shí)間,一旦超過(guò)規(guī)定的時(shí)間該
Cookie就會(huì)被系統(tǒng)清
除。例如在PHP中Cookie被用來(lái)跟蹤用戶進(jìn)程直到用戶離開(kāi)網(wǎng)站。持續(xù)的Cookie則保存在用戶的Cookie文件中,下一次用戶
返回時(shí),仍然可以
對(duì)它進(jìn)行調(diào)用。
要了解Cookie,必不可少地要知道它的工作原理。一般來(lái)說(shuō),Cookie通過(guò)HTTP Headers從服務(wù)器端返回到瀏覽器上。首
先,服務(wù)器端在響應(yīng)
中利用Set-Cookie header來(lái)創(chuàng)建一個(gè)Cookie,然后,瀏覽器在它的請(qǐng)求中通過(guò)Cookie header包含這個(gè)已經(jīng)創(chuàng)建的
Cookie,并且反它返回
至服務(wù)器,從而完成瀏覽器的論證。 例如,我們創(chuàng)建了一個(gè)名字為login的Cookie來(lái)包含訪問(wèn)者的信息,創(chuàng)建Cookie時(shí),
服務(wù)器端的Header如
下面所示,這里假設(shè)訪問(wèn)者的注冊(cè)名是"Michael Jordan",同時(shí)還對(duì)所創(chuàng)建的Cookie的屬性如path、domain、expires等進(jìn)
行了指定。
Set-Cookie:login=Michael Jordan;path=/;domain=msn.com;
expires=Monday,01-Mar-99 00:00:01 GMT
上面這個(gè)Header會(huì)自動(dòng)在瀏覽器端計(jì)算機(jī)的Cookie文件中添加一條記錄。瀏覽器將變量名為"login"的Cookie賦值
為"Michael Jordon"。注意
,在實(shí)際傳遞過(guò)程中這個(gè)Cookie的值是經(jīng)過(guò)了URLEncode方法的URL編碼操作的。
這個(gè)含有Cookie值的HTTP Header被保存到瀏覽器的Cookie文件后,Header就通知瀏覽器將Cookie通過(guò)請(qǐng)求以忽略路徑的方
式返回到服務(wù)器
,完成瀏覽器的認(rèn)證操作。
此外,我們使用了Cookie的一些屬性來(lái)限定該Cookie的使用。例如Domain屬性能夠在瀏覽器端對(duì)Cookie發(fā)送進(jìn)行限定,具
體到上面的例子,
該Cookie只能傳達(dá)室到指定的服務(wù)器上,而決不會(huì)跑到其他的如www.hp.com的Web站點(diǎn)上去。Expires屬性則指定了該
Cookie保存的時(shí)間期
限,例如上面的Cookie在瀏覽器上只保存到1999年3月1日1秒。當(dāng)然,如果瀏覽器上Cookie太多,超過(guò)了系統(tǒng)所允許的范
圍,瀏覽器將自動(dòng)對(duì)
它進(jìn)行刪除。至于屬性Path,用來(lái)指定Cookie將被發(fā)送到服務(wù)器的哪一個(gè)目錄路徑下。
說(shuō)明:瀏覽器創(chuàng)建了一個(gè)Cookie后,對(duì)于每一個(gè)針對(duì)該網(wǎng)站的請(qǐng)求,都會(huì)在Header中帶著這個(gè)Cookie;不過(guò),對(duì)于其他網(wǎng)
站的請(qǐng)求Cookie是
絕對(duì)不會(huì)跟著發(fā)送的。而且瀏覽器會(huì)這樣一直發(fā)送,直到Cookie過(guò)期為止。
2.2.2 要點(diǎn)方法
setcookie-----送出 Cookie 信息到瀏覽器。
語(yǔ)法: int setcookie(string name, string value, int expire, string path, string domain, int secure);
返回值: 整數(shù)
本函數(shù)會(huì)跟著標(biāo)識(shí) Header 送出一段小信息字符串到瀏覽器。使用本函數(shù)要在送出 HTML 數(shù)據(jù)前,實(shí)際上 cookie 也算標(biāo)
識(shí)的一部份。本函數(shù)的
參數(shù)除了第一個(gè) name 之外,都是可以省略的。參數(shù) name 表示 cookie 的名稱;value 表示這個(gè) cookie 的值,這個(gè)參
數(shù)為空字符串則表示取
消瀏覽器中該 cookie 的數(shù)據(jù);expire 表示該 cookie 的有效時(shí)間;path 為該 cookie 的相關(guān)路徑;domain 表示
cookie 的網(wǎng)站;secure 則
需在 https 的安全傳輸時(shí)才有效。想得到更多的 cookie 信息可以到
http://www.netscape.com/newsref/std/cookie_spec.html,由
cookie 原創(chuàng)者 Netscape 所提供的完整信息。
對(duì)于一個(gè)網(wǎng)站會(huì)員而言,經(jīng)常存在需要一次注冊(cè),多次認(rèn)證的問(wèn)題,例如我們經(jīng)常接觸到的論壇、社區(qū)等,一般采用手段
為cookie或 input
type=hidden來(lái)傳遞認(rèn)證參數(shù)。這里面有幾點(diǎn)隱患:
I. setcookie內(nèi)容必須完整包含帳號(hào)密碼,或類似的完整安全信息,如果只攜帶帳號(hào)信息或用某種權(quán)限標(biāo)志來(lái)認(rèn)證,極容
易造成非法入侵。
例如某站點(diǎn)中的會(huì)員更新頁(yè)面中攜帶的認(rèn)證信息是兩個(gè),用戶名和Uid(均為明文傳送)已知Uid對(duì)于每個(gè)會(huì)員是唯一的。由
于我們只需要知道對(duì)
方的帳號(hào)和Uid就可以更改對(duì)方信息(不需要知道密碼?。?,只要攻擊者知道Uid(攻擊者可以通過(guò)暴力猜測(cè)的方法來(lái)得到
Uid,有時(shí)候站點(diǎn)本身
也會(huì)泄露用戶的Uid,例如在論壇等處)那么,攻擊者就可以通過(guò)遍歷攻擊完成對(duì)任意一個(gè)帳號(hào)的信息更改。
II. 必須所有需要權(quán)限操作的頁(yè)面都必須執(zhí)行認(rèn)證判斷的操作。如果任何一頁(yè)沒(méi)有進(jìn)行這種認(rèn)證判斷,都有可能給攻擊者
以惡意入侵的機(jī)會(huì)。
III. 很多網(wǎng)站為了方便,將用戶名以及口令信息儲(chǔ)存在Cookie中,有的甚至以明文方式保存口令。如果攻擊者可以訪問(wèn)到
用戶的主機(jī),就可能
通過(guò)保存的Cookie文件得到用戶名和口令。
3. 腳本保護(hù)的問(wèn)題
3.1 概念介紹
在程序編寫(xiě)時(shí)優(yōu)秀的程序員都會(huì)知道,用有意義的變量名,文件名有助于增加程序的可讀性,具有良好的程序風(fēng)格。這個(gè)
非常好但在腳本語(yǔ)言不太
適合,為了不讓惡意用戶猜到你的變量或數(shù)據(jù)庫(kù)名等信息,必須改掉這些信息。動(dòng)態(tài)的網(wǎng)頁(yè)在服務(wù)器端執(zhí)行后返回給客戶
的是執(zhí)行后的代碼,這可
以保護(hù)服務(wù)器端的很多不想叫或不能叫瀏覽者知道的信息。安全是相對(duì)的,每天都在有新的安全漏洞被發(fā)現(xiàn),如果惡意的
用戶在你之前知道了一個(gè)
可以看你的腳本源代碼的漏洞或這個(gè)漏洞一時(shí)間無(wú)法修補(bǔ)怎么辦?
3.2 主意要點(diǎn)
建議用一些比較怪異的名字命名,刪掉腳本中的注釋。如果還需要保持程序的可讀性的話,可以建立一個(gè)映射,你可以寫(xiě)
個(gè)具有良好風(fēng)格的腳本程
序,然后再做一個(gè)變量名映射建立一個(gè)具有較安全命名方法的腳本,去掉這個(gè)腳本中的注視和所有能去掉的信息,修改時(shí)
作個(gè)同步就可以了
我們可以在程序的使用前對(duì)程序進(jìn)行加密,以保護(hù)我們自己的程序再萬(wàn)一的情況下部被泄漏。
3.3 保護(hù)方法
我看到過(guò)很多的對(duì)腳本的加密方法,都很不錯(cuò),有的是專門(mén)的加密軟件,有的是通過(guò)一些技巧加上利用語(yǔ)言的特性進(jìn)行加
密的,例如隨機(jī)生成一個(gè)
密匙,把密匙放在"不可見(jiàn)的"地方,通過(guò)一些算法對(duì)腳本進(jìn)行加解密,就是由于某些系統(tǒng)漏洞導(dǎo)致你的腳本源代碼泄漏,
也無(wú)濟(jì)于事。
4 .實(shí)例說(shuō)明
下面這個(gè)例子是在網(wǎng)上經(jīng)常被提到的,這是個(gè)非常經(jīng)典的例子,所以在這里通過(guò)這個(gè)實(shí)例告訴大家可能存在的危險(xiǎn)。
問(wèn)題描述:
大部分網(wǎng)站把密碼放到數(shù)據(jù)庫(kù)中,在登陸驗(yàn)證中用以下sql,(以asp為例)
sql="select * from user where username='"&username&"'and pass='"& pass &'"
此時(shí),您只要根據(jù)sql構(gòu)造一個(gè)特殊的用戶名和密碼,如:ben' or '1'='1
就可以進(jìn)入本來(lái)你沒(méi)有特權(quán)的頁(yè)面。再來(lái)看看上面那個(gè)語(yǔ)句吧:
sql="select * from user where username='"&username&"'and pass='"& pass&'"
此時(shí),您只要根據(jù)sql構(gòu)造一個(gè)特殊的用戶名和密碼,如:ben' or '1'='1 這樣,程序?qū)?huì)變成這樣:
sql="select*from username where
username="&ben'or'1'=1&"and pass="&pass&" or 是一個(gè)邏輯運(yùn)算符,作用是在判斷兩個(gè)條件的時(shí)候,只要其中一個(gè)條件成
立,那么等式
將會(huì)成立.而在語(yǔ)言中,是以1來(lái)代表真的(成立).那么在這行語(yǔ)句中,原語(yǔ)句的"and"驗(yàn)證將不再繼續(xù),而因?yàn)?1=1"和"or"令
語(yǔ)句返回為真值.。
另外我們也可以構(gòu)造以下的用戶名:
username='aa' or username<>'aa'
pass='aa' or pass<>'aa'
相應(yīng)的在瀏覽器端的用戶名框內(nèi)寫(xiě)入:aa' or username<>'aa 口令框內(nèi)寫(xiě)入:aa' or pass<>'aa,注意這兩個(gè)字符串兩頭是沒(méi)有'的。這樣就可以成功的騙過(guò)系統(tǒng)而進(jìn)入。
具體實(shí)施是這樣的,首先我會(huì)到注冊(cè)的地方去收集信息,了解盡可能多的信息,例如目標(biāo)數(shù)據(jù)庫(kù)中都有用戶的什么樣的信息,隨便的填寫(xiě)信息然后提交,當(dāng)你要注冊(cè)的用戶名被注冊(cè)的是有系統(tǒng)會(huì)提示你已被注冊(cè),有的網(wǎng)站做的更好的,就是他們專門(mén)給你設(shè)置的檢測(cè)是否有已經(jīng)被注冊(cè)的功能,通過(guò)這樣就會(huì)非常容易的找到目標(biāo)--那個(gè)提示已被注冊(cè)的用戶,讓后你在這個(gè)注冊(cè)頁(yè)里填寫(xiě)一些特殊的字符,如',/,,等字符看系統(tǒng)如何提示,以證明程序員是否注意到了應(yīng)該過(guò)濾字符或懂得是否應(yīng)該過(guò)濾那些字符,在這頁(yè)進(jìn)行嘗試是因?yàn)橛械木W(wǎng)站在登錄的時(shí)候他會(huì)記錄你的ip地址,當(dāng)然你也可以找一個(gè)比你直接登錄要快的代理服務(wù)器來(lái)做跳板。后面你要做的就是察看登錄頁(yè)的html源代碼,看看是否有在客戶端的字符過(guò)濾,看看這個(gè)程序員是用什么風(fēng)格來(lái)編寫(xiě)程序,盡可能多的了解程序編寫(xiě)風(fēng)格,這對(duì)你以后的某些判斷有好處。如果有在客戶端的過(guò)濾也不怕,你要搞清是什么樣的過(guò)濾,能不能對(duì)攻擊造成威脅,不要一看有過(guò)濾就害怕,可以嘗試著用別的方法繞,就是使用自己精心打造的獨(dú)立腳本,進(jìn)行攻擊。然后你要看看form的action中的url是否可以直接提交,在瀏覽器地址欄里直接提交,看看返回什么,是否有來(lái)路檢測(cè)。還有很多細(xì)小的地方,你也應(yīng)該可以注意到,例如那些地方程序員的整體的編寫(xiě)風(fēng)格是什么,變量名定義的風(fēng)格是什么等等,這個(gè)會(huì)幫我們"猜"到很多東西。還有別的其他什么,我也記不太清楚了,臨場(chǎng)發(fā)揮吧。通過(guò)這些了解我們有如下幾種可能:
1.那個(gè)程序員非常善良相信全世界都是好人,什么都沒(méi)做,根本沒(méi)有任何檢測(cè)機(jī)制,我們直接用username='aa' or
username<>'aa',
pass='aa' or pass<>'aa'就可以搞定,現(xiàn)在這么善良的人少啦,可是你要是有耐心,找到這種人還是不難的。
2.這個(gè)程序員可能聽(tīng)別人提起過(guò)一些安全問(wèn)題,畢竟現(xiàn)在這個(gè)那里都有人說(shuō),很多書(shū)中都有提及,但是做得不夠好,他只進(jìn)行了簡(jiǎn)單的輸入過(guò)濾。過(guò)濾有兩種方式,一種是在客戶端的過(guò)濾,一種是在服務(wù)器端的過(guò)濾?,F(xiàn)在很多的程序員考慮到再服務(wù)器端進(jìn)行過(guò)濾可能給服務(wù)器造成更多的負(fù)荷
,會(huì)把檢測(cè)過(guò)程放在客戶端。如果他在服務(wù)器端沒(méi)做任何事情,那么還是可以對(duì)其進(jìn)行攻擊的,我可以將這個(gè)登錄頁(yè)的源
代碼COPY下來(lái),然后自己建立一個(gè)文件把這些代碼PASTE進(jìn)去,再對(duì)這個(gè)文件進(jìn)行進(jìn)一步的深加工,去掉原來(lái)頁(yè)的過(guò)濾機(jī)制,或者直接將攻擊代碼寫(xiě)到這個(gè)文件中去,然后將form中的action中的地址改成絕對(duì)地址,也就是將文件名改成"http://www.target.com/targer.php"這樣,然后就可
以提交啦。但是如果服務(wù)器端加上了"來(lái)路檢測(cè)",你就白玩了。如果這樣還是不行,我再換一種方法,在瀏覽器的地址欄里用?來(lái)輸入?yún)?shù),就好像
"http://www.targer.com/targer.php?username='aa' or username<>'aa'&pass='aa' or pass<>'aa' "然后敲回車吧,其
實(shí)應(yīng)該先嘗試這種方法因?yàn)檫@用方法更簡(jiǎn)單,防護(hù)起來(lái)也很簡(jiǎn)單,這種提交方式不是post 而是get ,只要服務(wù)器端程序檢測(cè)你的提交方法,就可以kill掉這個(gè)陰謀。如果單純的只檢測(cè)了"來(lái)路",還是不太安全的,可以先正確的提交一次,在提交過(guò)程中馬上停止,就是保存這個(gè)環(huán)境,然后再構(gòu)造請(qǐng)求。
(我做過(guò)幾次試驗(yàn)得到的結(jié)果都不太一樣,應(yīng)該是和終止的時(shí)機(jī)有關(guān),歡迎大家來(lái)交流)。
3.一個(gè)很出色的程序員,安全意識(shí)非常高,他在服務(wù)器端做了如下檢測(cè):檢測(cè)提交的方法;檢測(cè)提交的"來(lái)路";檢測(cè)提交內(nèi)容的長(zhǎng)度;全面檢測(cè)提交內(nèi)容,這樣我們就很難通過(guò)上面的方法對(duì)其進(jìn)行攻擊,那到保密的資料就已經(jīng)不太可能了(如果各位還有什么好的辦法,請(qǐng)一定來(lái)信告訴小弟,小弟在這里先謝了)。但是我還想說(shuō)的是攻擊并不代表是非要入侵進(jìn)去,拿到某些東西才叫入侵,對(duì)你的機(jī)器進(jìn)行破壞也叫入侵啊,例如提交一些錯(cuò)誤的請(qǐng)求,腳本解釋程序就會(huì)非常規(guī)矩的給你返回錯(cuò)誤信息,最淺顯的后果就是暴露物理路經(jīng),有的時(shí)候一些特殊的請(qǐng)求會(huì)使web服務(wù)宕掉,這些個(gè)我認(rèn)為絕對(duì)是屬于攻擊,絕對(duì)是危害,也許你認(rèn)為暴露物理路徑?jīng)]有什么,是在單獨(dú)看來(lái)沒(méi)有什么,但要是在一個(gè)有計(jì)劃的攻擊里,這個(gè)就會(huì)發(fā)揮很多作用,那時(shí)你可能還會(huì)莫名為什么他們找到了我的文件呢。也許有人認(rèn)為這個(gè)是腳本解釋程序的bug,也許有的是,但是返回錯(cuò)誤信息絕對(duì)不是腳本解釋程序的錯(cuò)誤,這個(gè)是每個(gè)解釋程序都要做到的,在我看來(lái)這個(gè)應(yīng)該是還是程序員的問(wèn)題,程序員沒(méi)有做好對(duì)錯(cuò)誤的處理。每一本教你如何編寫(xiě)程序的書(shū)籍里基本都會(huì)有錯(cuò)誤處理之類的章節(jié),并且每種語(yǔ)言基本都有錯(cuò)誤處理函數(shù)和方法,只不過(guò)你沒(méi)有想到罷了。至于究竟要怎么處理那就要看你對(duì)cgi程序安全的熟悉程度了,那就要看你對(duì)這種腳本語(yǔ)言的特性熟悉多少了,說(shuō)到底就是經(jīng)驗(yàn),唯一的辦法就是多看多寫(xiě)多想多交流。
4.非常優(yōu)秀的程序員,以上那些做的都非常好(也許就是你啊,畢竟不難嘛,加上很少的代碼就可以了),怎么辦??怎么辦?!怎么辦??!在一旁偷偷的佩服吧!哈哈。
5. 其它注意事項(xiàng):思路和方法
指導(dǎo)思想:
I.嚴(yán)格控制程序與用戶交互的途徑
II.嚴(yán)格控制程序與用戶交互的內(nèi)容
III.盡可能好的保護(hù)我們控制
基本思路:
I.為沒(méi)一個(gè)功能寫(xiě)一個(gè)獨(dú)立的程序,程序頁(yè)
II.盡可能少的讓客戶了解你的服務(wù)器端信息
III.不要用"客戶應(yīng)該這么寫(xiě)"這個(gè)思路想問(wèn)題
IV.盡可能多的想到不可能發(fā)生的事情
基本方法:
盡可能多的控制交互:
I.檢測(cè)提交的方法,就是控制他的post還是get;
II.檢測(cè)提交的"來(lái)路",就是檢測(cè)一個(gè)環(huán)境變量HTTP_REFERER;
III.檢測(cè)提交內(nèi)容的長(zhǎng)度;
IV全面檢測(cè)提交內(nèi)容;
積極-消極防護(hù):
I.盡可能多的錯(cuò)誤處理,例如當(dāng)檢測(cè)到了不正確的輸入時(shí),應(yīng)該怎么做,是強(qiáng)制返回,還是發(fā)出警告;
II.充分發(fā)揮日志功用,例如在你檢測(cè)到了不正確的提交時(shí),就記錄下客戶端的信息,例如IP,系統(tǒng)配置,請(qǐng)求等等,畢竟現(xiàn)在是技術(shù)飛躍的時(shí)代,不能保證可以想到每一種可能,這也是我在這篇文章里不止一次提到"盡可能"這個(gè)詞的原因。充分的日志記錄不全是為了
抓住入侵者(如果入侵者使用了跳板,記錄了IP也是沒(méi)有用的),更重要的是為了能發(fā)現(xiàn)問(wèn)題的所在,找到問(wèn)題,改正問(wèn)題,亡羊補(bǔ)牢,這個(gè)才是最重要的。
III.充分發(fā)揮你的想象力,用一種入侵者的思想考慮問(wèn)題,用一種另類的思想考慮問(wèn)題,盡可能想到不可能發(fā)生的事,把問(wèn)題扼殺在萌芽里。
我們xundi哥說(shuō)的好:掌握方法?。。‖F(xiàn)在腳本語(yǔ)言層出不窮,asp,perl,php,jsp等等,基本不可能精通每一種,(也許你厲害,都能精通,我比較呆,會(huì)一個(gè)就不錯(cuò)啦),但是要是掌握了方法就不同了啊,各位網(wǎng)絡(luò)的精英舉一反三觸類旁通,肯定是優(yōu)秀的不得了。我寫(xiě)腳本一共也沒(méi)多少天,寫(xiě)這個(gè)東西我知道肯定是班門(mén)弄斧了,錯(cuò)誤之處還請(qǐng)各位大蝦抱著挽救和幫助的精神,告知小弟(方式、方法、態(tài)度不限),小弟我在這里先謝了。寫(xiě)這個(gè)東西,我只是想說(shuō)說(shuō)小弟的一些小的心得,與大家共勉,我想告訴大家的就是"領(lǐng)會(huì)精神",嘿嘿,"領(lǐng)會(huì)精
神"。大家要是有什么好的方法,希望不要保留,充分發(fā)揮網(wǎng)絡(luò)的自用共享,拿出來(lái),大家交流交流,不勝感激。
襲來(lái)的,這種東西小弟不敢自己寫(xiě)(嘿嘿,實(shí)際還有不少懶的成分,哈哈),希望大家不要見(jiàn)怪。