Фильтрация кодированного XSS в классическом ASP - PullRequest
4 голосов
/ 29 сентября 2011

ки.Я имею дело с классическим приложением ASP, написанным на VBScript.Я пытаюсь отфильтровать возможный XSS, который может прийти через закодированную строку запроса.

У меня есть простая функция исключения XSS [getUserInput].Это ищет специальные символы, такие как <> / '.... и заменяет их пробелом.Это работает очень хорошо.

Но, когда я вводю что-то, что закодировано через Server.URLEncode (VBScript) или escape (Javascript), очевидно, мой фильтр выше не работает.

Я хочу знать, какие существуют рекомендуемые решения для предотвращения этого конвертированного ввода в Unicode, который делает мою страницу уязвимой для XSS.

Шаги воспроизведения:

<%
Response.Write getUserInput(Request("txt1")) + "<br/>"
Response.Write Server.URLEncode(getUserInput(Request("txt1"))) + "<br/>"
'the below line is where I am trying to decode and echo the input
Response.Write URLDecode2((getUserInput(Request("txt1")))) + "<br/>"
Response.Write "<br/>"
%>

<html>
Try any of the below two encoded strings in the input box and hit the button. </br></br>
alert('hi') </br>
%3Cscript%3Ealert%28%27hi%27%29%3C%2Fscript%3E  <br/>
alert(document.cookie) </br>
%3Cscript%3Ealert%28document.cookie%29%3C%2Fscript%3E <br/> 
</br>
<form method="get" name="form1" id="form1" action="#" onSubmit="CallOnLoad()">
    <input type='text' name='txt1' id='txt1' />
    <button name='btn' type='submit' id='btn'>Hitme</button>
</form>
</html>

<%
function getUserInput(input)

dim newString
newString=input  
newString    = replace(newString,"--","")
newString    = replace(newString,";","")          
  newString    = replace(newString,chr(34),"'") 
  newString    = replace(newString,"'","") 
  newString    = replace(newString,"=","=") 
  newString    = replace(newString,"(","[") 
  newString    = replace(newString,")","]")
  newString = replace(newString,"'","''")
  newString = replace(newString,"<","[")
  newString = replace(newString,">","]")  
  newString = replace(newString,"/*","/") 
  newString = replace(newString,"*/","/")
  getUserInput = newString

end function
%>
<%
'URLDecode2 - source code from http://www.motobit.com/tips/detpg_URLDecode/ 
Function URLDecode2(ByVal What)

  Dim Pos, pPos
  What = Replace(What, "+", " ")
  on error resume Next
  Dim Stream: Set Stream = CreateObject("ADODB.Stream")
  If err = 0 Then 
    on error goto 0
    Stream.Type = 2 'String
    Stream.Open
    Pos = InStr(1, What, "%")
    pPos = 1
    Do While Pos > 0
      Stream.WriteText Mid(What, pPos, Pos - pPos) + _
        Chr(CLng("&H" & Mid(What, Pos + 1, 2)))
      pPos = Pos + 3
      Pos = InStr(pPos, What, "%")
    Loop
    Stream.WriteText Mid(What, pPos)
    Stream.Position = 0
    URLDecode2 = Stream.ReadText
    Stream.Close
  Else 'URL decode using string concentation
    on error goto 0
    Pos = InStr(1, What, "%")
    Do While Pos>0 
      What = Left(What, Pos-1) + _
        Chr(Clng("&H" & Mid(What, Pos+1, 2))) + _
        Mid(What, Pos+3)
      Pos = InStr(Pos+1, What, "%")
    Loop
    URLDecode2 = What
  End If
End Function
%>

Iтребуется разместить приложение на IIS 7.5 / Win 2008 R2.Простые / элегантные советы, пожалуйста?

Как: предотвратить межсайтовый скриптинг в ASP.NET - хорошая статья, но она не успокаивает мой сценарий, поскольку я имею дело с Classic ASP.

Спасибо.

Ответы [ 3 ]

8 голосов
/ 29 сентября 2011

Я пытаюсь отфильтровать возможные XSS

Это в значительной степени пустая трата времени.

Эта разновидность XSS является проблемой выходного каскада, вызванной вставкойданные в HTML без HTML-экранирования.

Несмотря на многочисленные усилия глубоко ошибочных инструментов и функций «анти-XSS», эту проблему просто невозможно решить путем фильтрации на этапе ввода.Во время ввода неизвестно, где заканчиваются данные, какие данные нужно будет экранировать HTML (в отличие от введения в другие текстовые контексты, такие как SQL или JavaScript), и какая обработка будет выполнена с этими данными до того, как они закончатся.на странице - в вашем примере вы демонстрируете это с помощью декодирования URL, но это может быть что угодно.

Чтобы исправить проблемы, вызванные < и &, вам нужно не забыть позвонить Server.HTMLEncode на каждую строку, которую вы вводите на страницу вывода, чтобы они были преобразованы в &lt; и &amp; соответственно.Это безопасно и также позволит пользователям использовать любой символ по своему желанию без исчезновения некоторых из них.(Представьте себе, что вы пытаетесь отправить это сообщение в SO со всеми удаленными <!)

Таким образом, вам не нужно беспокоиться о зашифрованных версиях <, потому что к тому времени, когда вы придете ких на странице, которую вы их расшифровали, и можете применять правильную форму кодировки, а именно HTML-экранирование.

Это не имеет ничего общего с Unicode.Не-ASCII символы могут быть включены в страницу без каких-либо проблем;это всего лишь <, &, а в значениях атрибута символ кавычки, используемый в качестве разделителя, представляет опасность при внедрении в HTML.

Раньше была проблема с слишком длинным UTF-8 последовательностей, где < может быть контрабандой в недопустимой последовательности байтов с верхним битом, которые могли бы пройти через HTML-кодирование без изменений.Тогда IE (и Opera) будут воспринимать это как настоящий <.Хотя по-прежнему целесообразно отфильтровывать оверлонги, если вы работаете с UTF-8 на языке, который имеет собственные строки байтов, а не Unicode, это не является необходимостью, как это было раньше, поскольку все современные основные браузеры корректно воспринимают оверлонги как недействительные недействительныепоследовательности.

При использовании правильного экранирования HTML ваш пример может выглядеть следующим образом (пропущена неизмененная функция URLDecode2):

<p>
    <%= Server.HTMLEncode( Request("txt1") ) %> <br/>
    <%= Server.HTMLEncode( URLDecode2(Request("txt1")) ) %>
</p>
<p>
    Try any of the below two encoded strings in the input box and hit the button.
</p>
<ul>
    <li>&lt;script>alert('hi')&lt;/script></li>
    <li>%3Cscript%3Ealert%28%27hi%27%29%3C%2Fscript%3E</li>
    <li>&lt;script>alert(document.cookie)&lt;/script></li>
    <li>%3Cscript%3Ealert%28document.cookie%29%3C%2Fscript%3E<li>
</ul>
<form method="get" action="this.asp">
    <input type="text" name="txt1" value="<%= Server.HTMLEncode( Request("txt1") ) %>"/>
    <input type="submit" value="Hitme"/>
</form>

(В ASP.NET 4.0 есть удобный <%: ярлык, чтобы сделать <%= Server.HTMLEncode для вас, к сожалению, не так в Classic ASP.)

1 голос
/ 14 февраля 2014

Когда у вас есть строки для анализа в asp вашего XML-сборщика. Вы можете создать это так:

<description><![CDATA[ "& descriptionString &"]]></description>

Вы можете использовать функцию зачистки HTML для удаления ненужных html или экранирования html тэгов:

Function stripHTML(strHTML)
Dim objRegExp, strOutput
Set objRegExp = New RegExp
    with objRegExp
        .Pattern = "<(.|\n)+?>"
        .IgnoreCase = True
        .Global = True
    end with

'Replace all HTML tag matches with the empty string
strOutput = objRegExp.Replace(strHTML, "")
Set objRegExp = Nothing

'Replace all < and > with &lt; and &gt;
strOutput = Replace(strOutput, "<", "&lt;")
strOutput = Replace(strOutput, ">", "&gt;")
stripHTML = strOutput   
 'Return the value of strOutput
End Function

Еще один способ предотвращения внедрения SQL. Например, выполните синтаксический анализ запросов request.querystrings в форме get / post.

function SQLInject(strWords)
 dim badChars, newChars, tmpChars, regEx, i
 badChars = array( _
 "select(.*)(from|with|by){1}", "insert(.*)(into|values){1}", "update(.*)set", "delete(.*)(from|with){1}", _
"drop(.*)(from|aggre|role|assem|key|cert|cont|credential|data|endpoint|event|f ulltext|function|index|login|type|schema|procedure|que|remote|role|route|sign| stat|syno|table|trigger|user|view|xml){1}", _
"alter(.*)(application|assem|key|author|cert|credential|data|endpoint|fulltext |function|index|login|type|schema|procedure|que|remote|role|route|serv|table|u ser|view|xml){1}", _
"xp_", "sp_", "restore\s", "grant\s", "revoke\s", _
"dbcc", "dump", "use\s", "set\s", "truncate\s", "backup\s", _
"load\s", "save\s", "shutdown", "cast(.*)\(", "convert(.*)\(", "execute\s", _
"updatetext", "writetext", "reconfigure", _
"/\*", "\*/", ";", "\-\-", "\[", "\]", "char(.*)\(", "nchar(.*)\(")  

 newChars = strWords
 for i = 0 to uBound(badChars)
     Set regEx = New RegExp
     regEx.Pattern = badChars(i)
     regEx.IgnoreCase = True
     regEx.Global = True
     newChars = regEx.Replace(newChars, "")
     Set regEx = nothing
 next
 newChars = replace(newChars, "'", "''")
 SqlInject = newChars
end function
1 голос
/ 29 сентября 2011

Вы должны использовать Unescape .

Function getUserInput(input)
dim newString
'***********************
newString=Unescape(input)
'***********************
newString    = replace(newString,"--","")
'etc ...
'etc ...
'etc ...
End Function
...