Think Like a Computer Scientist.

Welcome to the future.
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Web Client Guidance研究2

Posted on 2010-11-01 09:31  TerabyteX  阅读(356)  评论(0编辑  收藏  举报

1 为了防止跨站脚本,假设所有的输入都是恶意的,比如共享数据库、文件输入、Cookie值、QueryString变量、HTTP头部信息、有公共接口的Web服务、RSS订阅等等


2 有潜在危险的HTML标记:<applet> <body> <embed> <frame> <script> <frameset> <html> <iframe> <img> <style> <layer> <link> <ilayer> <meta> <object>


3 跨站脚本例子
<img src="javascript:alert('hello');">

<img src="java script:alert('hello');">

<img src="javascript:alert('hello');">

<style TYPE="text/javascript">
alert('hello');
</style>


4 防止跨站脚本
:对HTML编码、对URL编码、过滤用户的输入
<%@ Page Language="C#" ValidateRequest="false"%>

<script runat="server">

void submitBtn_Click(object sender, EventArgs e)
{
// Encode the string input
StringBuilder sb = new StringBuilder(HttpUtility.HtmlEncode(htmlInputTxt.Text));
// Selectively allow  <b> and <i>
sb.Replace("&lt;b&gt;", "<b>");
sb.Replace("&lt;/b&gt;", "");
sb.Replace("&lt;i&gt;", "<i>");
sb.Replace("&lt;/i&gt;", "");
Response.Write(sb.ToString());
}
</script>

编码的原则,只对有必要的输出进行编码,如

Response.Write("<b>First Name:</b> " + Microsoft.Security.Application.AntiXss.HtmlEncode(Request.Form["fname"]);

而不是

Response.Write(Microsoft.Security.Application.AntiXss.HtmlEncode("<b>First Name:</b> " + Request.Form["fname"]);

MVC中已经使用相关Helper方法的地方没必要再编码,因为Helper方法已经做了编码的处理,如

<%= Html.ActionLink(anchortext, "Modify") %>

ASP.NET 4.0中优先使用AntiXSS库或者<%:标记,<%:标记内部使用了HttpUtility.HtmlEncode方法,比如

<%: "output string" %> 相当于 <%= HttpUtility.HtmlEncode("output string") %>

如果URL输出到其它标记中,比如<a>标记中,则应使用HtmlAttributeEncode方法

<a href="<%= AntiXss.HtmlAttributeEncode(unsafeUrl) %>">Untrusted link example</a>

如果直接输出整个URL,则使用HtmlEncode方法
<%= AntiXss.HtmlEncode(unsafeUrl) %>

对内嵌的HTML进行编码

<%@ Page Language="C#" AutoEventWireup="true" ValidateRequest="false" %>

<html>
<form id="form1" runat="server">
<div>
Signature:&nbsp;<asp:TextBox ID="txtSampleSig" TextMode="MultiLine" Rows="5"
runat="server"><i>Paul</i> West<script>alert();</script>
</asp:TextBox><br />
<asp:Button ID="btnTest" runat="server" Text="Test Sig"
OnClick="btnTest_Click" /><br />
<asp:Literal ID="ltlSampleOut" runat="server"></asp:Literal>
</div>
</form>
</html>

<script runat="server">
protected void btnTest_Click(object sender, EventArgs e)
{
ltlSampleOut.Text = AntiXss.GetSafeHtmlFragment(txtSampleSig.Text);
}          
</Script>

使用innerText属性替代innerHTML


5 ASP.NET请求验证
(1) Web.config
<system.web>
<pages buffer="true" validateRequest="true" />
</system.web>

(2) 页面指令
<%@ Page Language="C#" ValidateRequest="false" %>

(3) ASP.NET MVC
[ValidateInput(false)]
public ActionResult Edit(UserData userData) {
}

6 使用frame的安全性设置
<frame security="restricted" src="http://www.somesite.com/somepage.htm"></frame>


7 设置正确的页面编码
(1) ASP.NET HTML
<meta http-equiv="Content Type" content="text/html; charset=utf-8" />

(2) ASP.NET
<%@ Page ResponseEncoding="utf-8" %>

(3) Web.config
<configuration>
<system.web>
<globalization
requestEncoding="utf-8"
responseEncoding="utf-8"/>
</system.web>
</configuration>


8 验证Unicode字符集
using System.Text.RegularExpressions;

if (!Regex.IsMatch(Request.Form["name"], @"^[a-zA-Z'.\s]{1,40}$"))
throw new ArgumentException("Invalid name parameter");


9 ASP.NET MVC中的ValidateAntiForgeryTokenAttribute
[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UpdateUser(UserData usr) {
}

<% using(Html.Form(“Account”, “UpdateUser”)) { %>
<%= Html.AntiForgeryToke%>
User Name: <%= Html.TextBox(“Username”) %><br />
<% } %


10 模块初始化示例
(1) Web Application
using Microsoft.Practices.Web.Unity;

public class MyApplicationBootstrapper : UnityBootstrapper
{
}

protected void Application_Start()
{
MyApplicationBootstrapper bootstrapper = new MyApplicationBootstrapper ();
bootstrapper.Run();
}

(2) MVC
using Microsoft.Practices.Web.Unity;

public class MyApplicationBootstrapper : UnityMvcBootstrapper
{
}

protected void Application_Start()
{
// Bootstrap the application.
MyApplicationBootstrapper bootstrapper = new MyApplicationBootstrapper();
bootstrapper.Run();
// This will register routes for the main application.
// Route registration for modules is done via the
// bootstrapper.Run() call above.
// AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}


也许你会对Web Client Guidance研究1感兴趣