在经典 ASP 中过滤编码的 XSS

发布于 2024-12-07 08:59:22 字数 3144 浏览 1 评论 0原文

好的。我正在处理一个用 VBScript 编写的经典 ASP 应用程序。我正在尝试过滤可能通过编码查询字符串出现的 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
%>

我需要在 IIS 7.5/Win 2008 R2 上托管该应用程序。 简单/优雅的建议好吗?

如何: Prevent Cross-Site Scripting in ASP.NET 是一篇好文章,但它并不适合我处理经典 ASP 的情况。

谢谢。

ok. I am dealing with a Classic ASP app written on VBScript. I am trying to filter possible XSS that might come via encoded Query string.

I have a simple XSS elimination function in place [getUserInput]. This looks for special charactors like < > / ' .... and replaces them with blank space. That works pretty well.

But, when I input something that is encoded via Server.URLEncode (VBScript) or escape (Javascript), obviously my above filter does not work.

I want to know the recommended solutions that are in place to prevent this Unicode converted input that makes my page vulnerable to XSS.

Repro steps:

<%
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 am required to host the app on IIS 7.5/Win 2008 R2.
Simple/elegant advices please?

How To: Prevent Cross-Site Scripting in ASP.NET is a good article, but it does not quiet to my scenario as I am dealing with Classic ASP.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迷雾森÷林ヴ 2024-12-14 08:59:22

我正在尝试过滤可能的 XSS

这很大程度上是浪费时间。

这种 XSS 是一个输出阶段问题,是由于将数据插入 HTML 而不对其进行 HTML 转义而引起的。

尽管“反XSS”工具和功能被严重误导,但这个问题根本无法通过输入阶段的过滤来解决。在输入时,不知道数据将在哪里结束,哪些数据需要进行 HTML 转义(而不是注入到 SQL 或 JavaScript 等其他文本上下文中),以及在数据结束之前将对该数据进行哪些处理在页面上 - 在您的示例中,您使用 URL 解码来演示这一点,但它可以是任何内容。

要纠正由 <& 引起的问题,您需要记住在每个上调用Server.HTMLEncode您注入到输出页面中的字符串,以便它们分别转换为 <&。这是安全的,并且还允许用户随意使用任何角色,而其中一些角色不会消失。 (想象一下尝试将此消息发布到 SO,并删除所有 <!)

这样您就无需担心 < 的编码版本,因为通过当您将它们放在页面上时,您将对其进行解码,并且可以应用正确的编码形式,即 HTML 转义。

这实际上与 Unicode 没有任何关系。非 ASCII 字符可以毫无问题地包含在页面中;只有 <& 以及在属性值中用作分隔符的引号字符在注入 HTML 时会带来危险。

过长的 UTF-8 序列曾经存在一个问题,其中 < 可能会被走私到无效的顶部位集字节序列中,而这些字节在通过 HTML 编码时不会发生变化。然后 IE(和 Opera)会将其视为真正的 <。虽然如果您使用具有本机字节字符串而不是 Unicode 的语言来使用 UTF-8,过滤超长仍然是一个好主意,但它不再像以前那样有必要,因为当前所有主要浏览器都正确地将超长视为非功能性无效序列。

使用正确的 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><script>alert('hi')</script></li>
    <li>%3Cscript%3Ealert%28%27hi%27%29%3C%2Fscript%3E</li>
    <li><script>alert(document.cookie)</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 中,有一个方便的 <%: 快捷方式不幸的是,在经典 ASP 中不是这样的。)

I am trying to filter possible XSS

This is largely a waste of time.

This breed of XSS is an output-stage issue, caused by inserting data into HTML without HTML-escaping it.

Despite the many efforts of deeply misguided “anti-XSS” tools and function, this problem simply cannot be handled by filtering at the input phase. At input time it is not known where data will end up, which data will need to be HTML-escaped (as opposed to injected into other text contexts like SQL or JavaScript), and what processing will be done to that data before it ends up on the page—in your example's case you're demonstrating this with URL-decoding, but it could be anything.

To correct problems caused by < and &, you need to remember to call Server.HTMLEncode on every string you inject into your output page, so that they'll be converted into < and & respectively. This is safe and will also allow users to use any character at will without some of them disappearing. (Imagine trying to post this message to SO with all the <s removed!)

That way you don't need to worry about encoded versions of <, because by the time you come to put them on the page you will have decoded them, and can apply the correct form of encoding, namely HTML-escaping.

This is not really anything to do with Unicode. Non-ASCII characters can be included in a page without any issues; it is only <, &, and in attribute values the quote character being used as a delimiter, that present any danger when injected into HTML.

There used to be a problem with over-long UTF-8 sequences, where a < could be smuggled in an invalid sequence of top-bit-set bytes that would get through HTML-encoding unchanged. Then IE (and Opera) would treat it as a real <. Whilst it's still a good idea to filter overlongs if you are working with UTF-8 in a language that has native byte strings rather than Unicode, it's not the necessity it once was as all current major browsers treat overlongs correctly, as non-functional invalid sequences.

Using correct HTML-escaping, your example might look like this (omitted the unchanged URLDecode2 function):

<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><script>alert('hi')</script></li>
    <li>%3Cscript%3Ealert%28%27hi%27%29%3C%2Fscript%3E</li>
    <li><script>alert(document.cookie)</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>

(In ASP.NET 4.0 there is a handy <%: shortcut to do <%= Server.HTMLEncode for you; unfortunately not so in Classic ASP.)

一指流沙 2024-12-14 08:59:22

您应该使用 Unescape

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

You should use Unescape.

Function getUserInput(input)
dim newString
'***********************
newString=Unescape(input)
'***********************
newString    = replace(newString,"--","")
'etc ...
'etc ...
'etc ...
End Function
被翻牌 2024-12-14 08:59:22

当您的 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 < and >
strOutput = Replace(strOutput, "<", "<")
strOutput = Replace(strOutput, ">", ">")
stripHTML = strOutput   
 'Return the value of strOutput
End Function

另一种用于防止 SQL 注入的函数。例如,从表单 get/post 解析 requests.querystrings。

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

When you have strings to parse in your xml builder asp. You could create it like so:

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

You could use a HTML stripping function to strip out unneeded html or escaping html tags:

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 < and >
strOutput = Replace(strOutput, "<", "<")
strOutput = Replace(strOutput, ">", ">")
stripHTML = strOutput   
 'Return the value of strOutput
End Function

Another one for preventing SQL injection. Parse for example requests.querystrings to it from Form 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文