top
Loading...
安全腳本程序的編寫V1.0
by Casper--------安全焦點
Casper@xfocus.org
http://www.xfocus.org

基本思路:
為沒一個功能寫一個獨立的程序,程序頁
盡可能少的讓客戶了解你的服務器端信息
不要用"客戶應該這么寫"這個思路想問題
盡可能多的想到不可能發生的事情

1.關于交互式動態網頁可能存在的問題
1.1 form類型的交互
1.1.1 概念介紹
在我們和瀏覽者進行交互時,最常用到的就是form(post/get/put方法),雖然非常方便,但是很多問題也是因他而起。form表單中input標志
用來接受用戶輸入的信息,例如:用戶名、密碼、email等。如果你沒有對用戶輸入進行很好的檢查的話,一個惡意的用戶會屏蔽掉一些安全機
制,繞過安全認證。例如,輸入標準的HTML語句或者javascript語句會改變輸出結果 ,在輸入框中打入標準的HTML語句會得到什么樣的結果呢?比如一個留言本,我們留言內容中打入:<font size=10>你好!</font> 如果你的程序中沒有屏蔽html語句,那么就會改變"你好"字體的
大小。在留言本中改變字體大小和貼圖有時并不是什么壞事,反而可以使留言本生動。但是如果在輸入框中寫個 javascript 的死循環,比如:
<a herf="http://someurl" onMouseover="while(1) {window.close('/')}">第一萬個驚心動魄</a> 那么其他查看該留言的客人只要移
動鼠標到"第一萬個驚心動魄",上就會使用戶的瀏覽器因死循環而死掉。
1.1.2 防范要點
(1)對特殊字符進行過濾
([&;`'\|"*?~<>^()[]{}$])/\$1/g;),這個是最基本的,在很多地方也已經不只一次提到過
<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([&;`'\|"*?~<>^()[]{}$])/\$1/g;,"")
var tmpstr = tmpstr.replace([&;`'\|"*?~<>^()[]{}$])/\$1/g;,"")
return (tmpstr.length==0)
}

function check()
{
tf=document.inputform
errors=""
if (isEmpty("username")) errors += "用戶名不能為空。";
if (isEmpty("password")) errors += "密碼不能為空!"
if (errors!="")
alert(errors);
return (errors=="")
}
(2) 對輸入的字符長度進行限制
(3) 進行盡可能多的錯誤出理和錯誤陷阱
(4) 盡可能多的使用以下這些標志,減少用戶輸入的機會
<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 概念介紹
這種類型的問題主要是瀏覽者可以通過瀏覽器的地址欄對腳本頁通過添加參數來和服務器進行交互,這些參數已經繞過放在客戶端提交頁的輸入檢
查了,還有就是可以通過地址欄輸入較長的參數或惡意編造的代碼造成服務器異常運算錯誤,導致服務器宕機或緩沖區溢出。

1.2.2 防范要點
(1) 盡量不要讓瀏覽者了解到你的運算提交頁
(2) 不允許地址欄提交參數
例如ASP程序中的request.serverVariables(QUERY_STRING)檢測是否有參數,如果有則使用response.redirect()強制返回指定頁,可以
是首頁,或者你自己做的警告頁。
(3) 腳本頁間傳遞參數不要再瀏覽器欄顯示,盡可能少的讓瀏覽者了解你的程序規則、參數等
例如ASP中的Request.form和Request.QueryString這兩個數據集合分別使用的是post和get方法,我們盡量不要是用Request.QueryString這個數據集合,盡可能少的讓瀏覽者有和你交互的機會,

2. 安全認證的問題
2.1 需要安全認證密碼認證的可能存在的問題
2.1.1 概念介紹
現在流行的CGI應用程序傾向于收集信用卡信息。數據收集是CGI 應用程序的一個簡單的任務,但是敏感信息的
收集需要一個將信息從瀏覽器傳送給服務器和CGI程序的安全途徑。

舉個例子,假設我要通過Internet來銷售書。我可能在瀏覽器上建立一個表單,允許要購書的顧客通過表單提交它的個人信息和信用卡號碼。受
到這些信息后,我會將它們存儲到我的計算機作為商業記錄。

如果有人侵入我的商業計算機,那么他可能會訪問存放顧客信息和信用卡號碼的機密數據。為了避免這種情況,我會審查我的計算機配置安全了
,并確定用來接受表單的CGI腳本不會被惡意的操縱。換句話說,我,作為計算機的系統管理員和CGI程序員,要盡力控制住第一個問題:防止
信息直接從我的計算機中被竊取。

然而,怎樣防止當信息由客戶端發往服務器過程中有人中途竊取呢?記住信息怎樣由Web服務器傳送到CGI程序了嗎?信息通過網絡由瀏覽器先
傳送到服務器,然后服務器將信息傳送給CGI程序。這些信息可能在由客戶機傳送到服務器時被中途竊取(如圖2)。注意,為了保護信息使其不會
被中途竊取,必須在客戶和服務器之間進行加密。當然,如果你的客戶機不能識別的話,你不能執行特定CGI的加密。

由于Web處理的特點,使用你獨有的單獨通過CGI程序實現的安全處理協議的唯一途徑是:在表單信息通過瀏覽器傳送到服務器之前將其加密。
這個方案如。

之前,發展你自己的安全處理協議幾乎是不可能的。感謝Java這樣的語言,最近在客戶端處理所作的創新,使得這個發展變成可能。 方法是產生
一個標準HTML格式擴展的Java接口。當Java的提交按鈕被選擇時,Java Applet會在利用標準的POST HTTP請求將它發送到Web服務器前先
將值加密。

使用Java作為客戶機來發送和接收加密的數據將允許你使用自己定制的加密方案,而不需要一個昂貴的商業服務器。

因此,在網絡上安全保密地傳送數據信息需要調整瀏覽器和服務器之間的通信路徑,有一些是不能僅僅靠CGI就能夠控制的。目前有兩種加密客
戶機/服務器信息處理的建議:SSL(Secure Sockets Layer)和SHTTP(Secure HTTP),分別由Netscape和EIT(Enterprise Integrations
Technology)提議。關于這點,目前還不清楚哪一個將成為標準;很多公司在他們的服務器中兩種都采用了。因此,知道如何在這兩者中編寫
CGI程序是很有用的。

SSL是一個協議獨立的加密方案,在網絡信息包的應用層和傳輸層之間提供了安全的通道(參照圖5)。簡單說來,就是HTML或CGI經過了幕后的
服務器進行了加密處理,然而對HTML和CGI的作者來說是透明的。

因為客戶端和服務器端網絡程序處理加密過程,幾乎你的所有的CGI腳本不需要進行安全事務的修正。有一個顯著的例外。一個nph(no-parse-
header)的CGI程序繞過服務器而直接與客戶端進行通信。因此,nph的CGI腳本不會經過加密處理,因為信息未得到加密。受此影響的一個值得
注意的CGI應用程序是Netscape服務器推動的動態實現(Netscape server-push animations)。我懷疑這是主要應該值得注意的,然而,更
有可能因為要安全的傳輸敏感信息而犧牲頁面中的動畫。

SHTTP采用一種和SSL不同的方法。它通過擴展HTTP協議(應用層)來運作,優于一個較低層。因此,盡管SSL可以應用于所有的網絡服務,然而
SHTTP是一個特定的Web協議。

另外,還有其它的優點。作為HTTP的擴展集,SHTTP全兼容于HTTP和SHTTP的瀏覽器和服務器。為了使用SSL,你必須有一個支持SSL的瀏覽
器和服務器。另外,SHTTP是一個更靈活的協議。例如,這個服務器可以指定首選的加密方案。

SHTTP處理依賴于附加的HTTP頭。因此,如果你想讓你的CGI程序采用SHTTP的加密處理,你需要包含適當的頭。例如,替換簡單返回HTTP頭

Content-type:text/html

當一個SHTTP服務器從CGI應用程序中收到這個信息,它會知道在將其發送到瀏覽器之前將信息加密。一個非SHTTP的瀏覽器將忽略附加的頭。

關于使用SHTTP的更多的信息,請參照SHTTP的說明書:

http://www.commerce.net/information/standards/drafts/shttp.txt


2.1.3 腳本解析

下面是我以前寫的一段asp腳本,做了一些修改,把他貼出來,讓大家看看我加入了設置,那里做的不夠好。我在這里就不多說了,有興趣可以到
我的論壇來大家討論。

<!--#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="密碼錯啦"
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>錯了
</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

北斗有巢氏 有巢氏北斗