确定。我正在处理在VBScript上编写的经典ASP应用程序。我试图过滤可能来自编码查询字符串的可能的XSS。
我有一个简单的XSS消除函数[getUserInput]。这会寻找像<等特殊字符。 > /'....并用空格替换它们。这非常有效。
但是,当我输入通过Server.URLEncode(VBScript)或转义(Javascript)编码的内容时,显然我的上述过滤器不起作用。
我想知道推荐的解决方案,以防止这种Unicode转换输入使我的页面容易受到XSS攻击。
Repro步骤:
<%
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上托管应用程序。 请简单/优雅的建议?
How To: Prevent Cross-Site Scripting in ASP.NET是一篇很好的文章,但是当我处理Classic ASP时,它对我的场景并不安静。
感谢。
答案 0 :(得分:8)
我正在尝试过滤可能的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中,有一个方便的<%:
快捷方式可以为您执行<%= Server.HTMLEncode
;不幸的是,在经典ASP中没有这样做。)
答案 1 :(得分:1)
您应该使用Unescape。
Function getUserInput(input)
dim newString
'***********************
newString=Unescape(input)
'***********************
newString = replace(newString,"--","")
'etc ...
'etc ...
'etc ...
End Function
答案 2 :(得分:1)
当您在xml构建器asp中解析字符串时。您可以像这样创建它:
<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