SQL Injection、JS/HTML 腳本攻擊頻發,眾站點深受其擾。異於主機漏洞可打補丁,Web 攻擊源於程式碼缺陷,防範修復極不便。站長痛點:密碼再強也被偷、Supermaster 密碼外洩、程式碼未完善。本文從攻擊途徑剖析,給出代碼級防禦全攻略。
' 過濾關鍵字元,輸出安全編碼
Function CHK(fqyString)
fqyString = Replace(fqyString, ">", ">")
fqyString = Replace(fqyString, "<", "<")
fqyString = Replace(fqyString, "'", "'") ' 單引號實體化
fqyString = Replace(fqyString, """, """) ' 雙引號實體化
fqyString = Replace(fqyString, Chr(32), " ") ' 空格正規化
fqyString = Replace(fqyString, Chr(9), " ") ' Tab 正規化
fqyString = Replace(fqyString, Chr(13), "") ' 移除 CR
fqyString = Replace(fqyString, Chr(10) & Chr(10), "</P><P> ") ' 雙換行段落
fqyString = Replace(fqyString, Chr(10), "<BR> ") ' 單換行換行標籤
CHK = fqyString
End Function
使用方式: 將函數放入公共 include 檔,所有輸出點統一調用:
`<%=CHK(Username)%>` 或 `Username = CHK(Replace(Request("username"), "'", ""))`
錯誤寫法 (字串拼接):
sql = "SELECT * FROM admin WHERE username='" & user & "' AND password='" & pwd & "'"
正確寫法 (ADO 參數化命令):
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = conn
cmd.CommandText = "SELECT * FROM admin WHERE username=? AND password=?"
cmd.Parameters.Append cmd.CreateParameter("@user", 200, 1, 50, user) ' adVarChar, adParamInput, size
cmd.Parameters.Append cmd.CreateParameter("@pwd", 200, 1, 50, pwd)
Set rs = cmd.Execute
原理: 參數與 SQL 碼完全分離,資料永遠不會被解釋為代碼,徹底杜絕注入。
<%
On Error Resume Next
Dim strTemp
strTemp = LCase(Request.ServerVariables("URL") & "?" & Request.QueryString)
' 亦可檢查 Request.Form (POST)
If InStr(strTemp, "select%") Or InStr(strTemp, "insert%") Or InStr(strTemp, "delete%20from") Or InStr(strTemp, "count(") Or InStr(strTemp, "drop%20table") Or InStr(strTemp, "update%") Or InStr(strTemp, "truncate%") Or InStr(strTemp, "asc(") Or InStr(strTemp, "mid(") Or InStr(strTemp, "char(") Or InStr(strTemp, "xp_cmdshell") Or InStr(strTemp, "exec%20master") Or InStr(strTemp, "net%20localgroup%20administrators") Or InStr(strTemp, ":") Or InStr(strTemp, "net%20user") Or InStr(strTemp, "'") Or InStr(strTemp, "%20or%20") Then
Response.Write "<script>alert('非法地址!!');location.href='error.asp';</script>"
Response.End
End If
%>
放在全站 include 頭部,攔截明文關鍵字攻擊。注意: 會誤攔正常含關鍵字內容,需結合語境調優,絕不能替代參數化查詢。
<script language="javascript">
var url = location.search;
var re = /^\?(.*)(select%20|insert%20|delete%20from%20|count\(|drop%20table|update%20truncate%20|asc\(|mid\(|char\(|xp_cmdshell|exec%20master|net%20localgroup%20administrators|"|:|net%20user|'|%20or%20)(.*)$/gi;
if (re.test(url)) {
alert("地址中含有非法字符~");
location.href = "error.asp";
}
</script>
僅能攔截 URL 參數攻擊,無法防禦 POST 體、Cookie、Header 攻擊,且可被繞過,僅作第一層輕量阻擋。
bool CheckParams(params object[] args) {
string[] Lawlesses = { "=", "'" }; // 自定義非法字元
if (Lawlesses == null || Lawlesses.Length <= 0) return true;
string str_Regex = ".*[";
for (int i = 0; i < Lawlesses.Length - 1; i++)
str_Regex += Lawlesses[i] + "|";
str_Regex += Lawlesses[Lawlesses.Length - 1] + "].*";
foreach (object arg in args) {
if (arg is string) {
if (Regex.Matches(arg.ToString(), str_Regex).Count > 0) return false;
}
else if (arg is ICollection) {
foreach (object obj in (ICollection)arg) {
if (obj is string && Regex.Matches(obj.ToString(), str_Regex).Count > 0) return false;
}
}
}
return true;
}
可擴展為屬性/模型驗證特性 (Attribute),套用於 MVC/WebAPI 參數綁定前。
Web 腳本攻擊防禦的核心是「輸入驗證白名單 + 輸出編碼 + 參數化查詢」鐵三角。代碼層面落實 `CHK` 過濾、參數化查詢;系統層面部署 WAF、最小權限資料庫、安全標頭;管理層面建立 SDL (安全開發生命週期)、定期審計演練。唯有代碼、系統、管理三位一體,才能徹底斬斷 SQLi、XSS、遠端注入等 Web 攻擊鏈。