2.4 SQL注入式攻击
◎ 使用SQL参数API
正如前文“篡改参数”部分描述的,攻击者可以在输入域中插入特殊字符,改变SQL查询的本意,欺骗数据库服务器执行恶意的查询。
■ 风险分析
恶意查询有可能获取后端数据库保存的任何信息,例如客户信用卡号码的清单。
■ 解决方案
除了前面介绍的办法——用程序代码确保输入内容只包含有效字符,另一种更加健壮的办法是使用SQL参数API(例如ADO.NET提供的API),让编程环境的底层API(而不是程序员)来构造查询。
使用这些API时,开发者或者提供一个查询模板,或者提供一个存储过程,然后指定一系列的参数值,由底层API将参数值嵌入到查询模板,然后将构造出来的查询提交给服务器查询。这种办法的好处是确保参数能够正确地嵌入,例如,系统将对引号进行转义处理,从根本上杜绝SQL注入式攻击的发生。同时,在表单中引号仍是一个允许输入的有效字符,这也是使用底层API的一个优点。
按照这种思路修改前文“篡改参数”部分的例子,结果如下:- <div align=center>SqlDataAdapter my_query = new SqlDataAdapter("SELECT * FROM accounts
- WHERE acc_user= @user AND acc_password=@pass", the_connection);
- SqlParameter userParam = my_query.Select_Command.Parameters.Add(
- "@user",SqlDb.VarChar,20);
- userParam.Value=user;
- SqlParameter passwordParam = my_query.Select_Command.Parameters.Add(
- "@",SqlDb.VarChar,20);
- passwordParam.Value=password;
-
- </div>
复制代码 2.5 跨站脚本执行
◎ 对外发的数据进行编码
跨站脚本执行(Cross-site scripting)是指将恶意的用户输入嵌入到应答(HTML)页面。例如,下面的ASP.NET页面虽然简单,却包含着一个重大的安全缺陷:- <div align=center><%@ Page Language="vb" %>
- <asp:Label id="Label1" runat="server">
- 标签文字
- </asp:Label>
- <form method="post" runat="server" ID="Form1">
- 请在此处输入反馈信息
- <asp:Textbox ID="feedback" runat="server"/>
- <asp:Button id="cmdSubmit" runat="server"
- Text="提交!" OnClick="do_feedback">
- </asp:Button>
- </form>
- <script runat="server">
- Sub do_feedback(sender As Object, e As System.EventArgs)
- Label1.Text=feedback.Text
- End Sub
- </script>
-
- </div>
复制代码 ■ 风险分析
攻击者可以用javascript代码构造一个恶意的查询,点击链接时javascript就会运行。举例来说,脚本可以通过下面的用户输入来嵌入:- <div align=center><script>alert(documents.cookie)
- </script>
-
- </div>
复制代码 ■ 解决方案
在一个双层的安全体系中,对HTML页面中出现的外发用户数据执行输入验证和HTML编码,确保浏览器只把用户输入数据当成纯粹的文本,而不是其他具有特殊含义的内容,例如HTML代码、javascript脚本。
对于本例,只要加入一个HtmlEncode调用即可:- <div align=center>Label1.Text=Server.HtmlEncode(feedback.Text)
-
- </div>
复制代码 这样,应答HTML流将包含用户输入内容的HTML编码版本,也就是说,浏览器不会执行用户输入的javascript代码,因为根本不存在HTML的- <div align=center>“<SCRIPT>”
-
- </div>
复制代码 标记,用户输入的“<”和“>”字符已经被替换成HTML编码版本,即“<”和“>”。
[ 本帖最后由 饺子 于 2008-4-12 21:30 编辑 ] |