Как предотвратить XSS в классической ASP многочастной форме? - PullRequest
1 голос
/ 04 августа 2010

У меня есть составная форма, написанная на классическом ASP, основанная на приведенном ниже коде. Я использую хранимые процедуры и параметры для записи в базу данных sql, я использую 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 %>
    " method="post">
    ">

    <%
    ' 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("" & 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
            %>
            
            
                Name:
                ">
            
                Email:
                ">
            
            
            <%
        Case 2
            %>
            
            
                Address:
                ">
            
                City:
                ">
            
                State:
                ">
            
                Zip:
                ">
            
            
            <%
        Case 3
            ' Notice that you can do other types of form fields too.
            %>
            
            
                Sex:
                
                    >Male
                    >Female
                
            
                Age:
                
                    
                
            
            
            <%
        Case Else
            ' You shouldn't see this error unless something goes wrong.
            Response.Write("Error: Bad Page Number!")
    End Select
    %>
    
<!-- Display form navigation buttons. --> <% If intCurrentPage > 1 Then %> <% End If %> <% If intCurrentPage < NUMBER_OF_PAGES Then %> <% Else %> <% End If %> <% 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 %> Here's what you entered: Name: <%= Request.Form("1_name") %> Email: <%= Request.Form("1_email") %> Address: <%= Request.Form("2_address") %> City: <%= Request.Form("2_city") %> State: <%= Request.Form("2_state") %> Zip: <%= Request.Form("2_zip") %> Sex: <%= Request.Form("3_sex") %> Age: <%= Request.Form("3_age") %>

"> Начать заново

<% End If %>

1 Ответ

2 голосов
/ 04 августа 2010

Вы должны использовать 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
...