我有一个基于下面代码的经典 ASP 编写的多部分表单。我使用存储过程和参数写入 sql DB,在提交之前我也使用 Server.HTMLEncode。我有基于 javascript 的验证(jquery 验证插件)以及所有字段的服务器端 ASP 验证。我不担心注入,但该页面容易受到下面列出的 XSS 代码的攻击。
我的问题是:如何防止在像下面这样的经典 ASP 页面上出现这种类型的跨站点脚本?
基本上,所有数据都是在提交后的最后一个“页面”上收集的,我通过服务器端验证运行它。但我需要知道如何在用户到达提交点之前防止 XSS。
XSS代码:
';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>
代码:
<%
Const NUMBER_OF_PAGES = 3
Dim intPreviousPage
Dim intCurrentPage
Dim strItem
' What page did we come from?
intPreviousPage = Request.Form("page")
' What page are we on?
Select Case Request.Form("navigate")
Case "< Back"
intCurrentPage = intPreviousPage - 1
Case "Next >"
intCurrentPage = intPreviousPage + 1
Case Else
' Either it's our first run of the page and we're on page 1 or
' the form is complete and pages are unimportant because we're
' about to process our data!
intCurrentPage = 1
End Select
' If we're not finished then display the form.
If Request.Form("navigate") <> "Finish" Then %>
<form action="<%= Request.ServerVariables("URL") %>" method="post">
<input type="hidden" name="page" value="<%= intCurrentPage %>">
<%
' Take data and store it in hidden form fields. All our fields are
' prefixed with numbers so that we know what page it belongs to.
For Each strItem In Request.Form
' Ignore the "page" and "navigate" button form fields.
If strItem <> "page" And strItem <> "navigate" Then
' If the data is from the current page we don't need
' the hidden field since the data will show in the visible
' form fields.
If CInt(Left(strItem, 1)) <> intCurrentPage Then
Response.Write("<input type=""hidden"" name=""" & strItem & """" _
& " value=""" & Request.Form(strItem) & """>" & vbCrLf)
End If
End If
Next
' Display current page fields. The fields are all named with
' numerical prefix that tells us which page they belong to.
' We need a Case for each page.
Select Case intCurrentPage
Case 1
%>
<table>
<tr>
<td><strong>Name:</strong></td>
<td><input type="text" name="1_name" value="<%= Request.Form("1_name") %>"></td>
</tr><tr>
<td><strong>Email:</strong></td>
<td><input type="text" name="1_email" value="<%= Request.Form("1_email") %>"></td>
</tr>
</table>
<%
Case 2
%>
<table>
<tr>
<td><strong>Address:</strong></td>
<td><input type="text" name="2_address" value="<%= Request.Form("2_address") %>"></td>
</tr><tr>
<td><strong>City:</strong></td>
<td><input type="text" name="2_city" value="<%= Request.Form("2_city") %>"></td>
</tr><tr>
<td><strong>State:</strong></td>
<td><input type="text" name="2_state" value="<%= Request.Form("2_state") %>"></td>
</tr><tr>
<td><strong>Zip:</strong></td>
<td><input type="text" name="2_zip" value="<%= Request.Form("2_zip") %>"></td>
</tr>
</table>
<%
Case 3
' Notice that you can do other types of form fields too.
%>
<table>
<tr>
<td><strong>Sex:</strong></td>
<td>
<input type="radio" name="3_sex" value="male" <% If Request.Form("3_sex") = "male" Then Response.Write("checked=""checked""") %>>Male
<input type="radio" name="3_sex" value="female" <% If Request.Form("3_sex") = "female" Then Response.Write("checked=""checked""") %>>Female
</td>
</tr><tr>
<td><strong>Age:</strong></td>
<td>
<select name="3_age">
<option></option>
<option<% If Request.Form("3_age") = "< 20" Then Response.Write(" selected=""selected""") %>>< 20</option>
<option<% If Request.Form("3_age") = "20 - 29" Then Response.Write(" selected=""selected""") %>>20 - 29</option>
<option<% If Request.Form("3_age") = "30 - 39" Then Response.Write(" selected=""selected""") %>>30 - 39</option>
<option<% If Request.Form("3_age") = "40 - 49" Then Response.Write(" selected=""selected""") %>>40 - 49</option>
<option<% If Request.Form("3_age") = "50 - 59" Then Response.Write(" selected=""selected""") %>>50 - 59</option>
<option<% If Request.Form("3_age") = "60 - 69" Then Response.Write(" selected=""selected""") %>>60 - 69</option>
<option<% If Request.Form("3_age") = "70 - 79" Then Response.Write(" selected=""selected""") %>>70 - 79</option>
<option<% If Request.Form("3_age") = "80 +" Then Response.Write(" selected=""selected""") %>>80 +</option>
</select>
</td>
</tr>
</table>
<%
Case Else
' You shouldn't see this error unless something goes wrong.
Response.Write("Error: Bad Page Number!")
End Select
%>
<br />
<!-- Display form navigation buttons. -->
<% If intCurrentPage > 1 Then %>
<input type="submit" name="navigate" value="< Back">
<% End If %>
<% If intCurrentPage < NUMBER_OF_PAGES Then %>
<input type="submit" name="navigate" value="Next >">
<% Else %>
<input type="submit" name="navigate" value="Finish">
<% End If %>
</form>
<%
Else
' This is where we process our data when the user submits the final page.
' I just display the data, but you're free to store the data in a
' database, send it via email, or do whatever you want with it.
'For Each strItem In Request.Form
' Response.Write(strItem & ": " & Request.Form(strItem) & "<br />" & vbCrLf)
'Next
%>
<p><strong>
Here's what you entered:
</strong></p>
<pre>
<strong>Name:</strong> <%= Request.Form("1_name") %>
<strong>Email:</strong> <%= Request.Form("1_email") %>
<strong>Address:</strong> <%= Request.Form("2_address") %>
<strong>City:</strong> <%= Request.Form("2_city") %>
<strong>State:</strong> <%= Request.Form("2_state") %>
<strong>Zip:</strong> <%= Request.Form("2_zip") %>
<strong>Sex:</strong> <%= Request.Form("3_sex") %>
<strong>Age:</strong> <%= Request.Form("3_age") %>
</pre>
<p>
<a href="<%= Request.ServerVariables("URL") %>">Start Again</a>
</p>
<%
End If
%>