2010-08-03 61 views
1

我有一个基于下面代码的经典ASP编写的多部分表单。我使用存储过程和参数来写入sql数据库,我在使用Server.HTMLEncode之前也提交了它。我有基于JavaScript的验证(jQuery验证插件)以及服务器端的所有领域的ASP验证。我并不担心注射,但该页面容易受到下面列出的XSS代码的影响。如何防止经典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> 

CODE:

<% 
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""") %>>&lt; 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="&lt; Back"> 
    <% End If %> 
    <% If intCurrentPage < NUMBER_OF_PAGES Then %> 
     <input type="submit" name="navigate" value="Next &gt;"> 
    <% 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 
%> 

回答

2

书写用户输入到页面之前,您应该使用Server.HTMLEncode,不写入数据库之前。事实上,最好将非编码值存储在数据库中以避免重复编码。

固定码:

Case 1 
%> 
<table> 
    <tr> 
    <td><strong>Name:</strong></td> 
    <td><input type="text" 
       name="1_name" 
       value="<%= Server.HTMLEncode(Request.Form("1_name")) %>"></td> 
    </tr> 
    <tr> 
    <td><strong>Email:</strong></td> 
    <td><input type="text" 
       name="1_email" 
       value="<%= Server.HTMLEncode(Request.Form("1_email")) %>"></td> 
    </tr> 
</table> 
<% 

同时,确保Request.Form("page")是一个数字

intPreviousPage = TryCLng(Request.Form("page")) 

矿的内部功能

function TryCLng(NumeroEnTexto) 
    if isNumeric(NumeroEnTexto) then 
     TryCLng = clng(NumeroEnTexto) 
    else 
     TryCLng = 0 
    end if 
end function 
+0

Server.HTMLEncode似乎并没有工作。 由于页面发回给自己,在我“提交”数据的第一页并让我们说像'asdf'这样的一些html,然后看页面重新加载后的源,我看到这个: asdf”> 即使使用'value =“<%= Server.HTMLEncode(Request.Form(”1_name“))%>”'它仍然呈现html中的隐藏的领域。 这怎么可能? – jethomas 2010-08-04 15:32:01

+0

如果你仍然有问题,你可以发布一个链接到演示页面吗? – 2013-08-08 21:23:34