[研究]Eval與一些HtmlEncode、HtmlSanitizer與Fortify SCA的XSS (Cross-Site Scripting)檢測
2021-11-20
2024-02-26更新
環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19
********************************************************************************
某些程式寫法
<a href="####" onclick="window.open('MyGroupForm.aspx?MyGroupID=<%# Eval("MyGroupID") %>', '', 'scrollbars=yes,resizable=yes,width=800,height=700,left=10,top=10');">編輯</a>
<a href="MyGroupDelete.aspx?MyGroupID=<%#Eval("MyGroupID")%>&p=<%=p%>" onclick="return confirm('確定要刪除嗎?');" >刪除</a>
<asp:Label ID="lb_MyGroupName" runat="server" Text='<%# Eval("MyGroupName") %>' />
Fortify SCA 檢查會出現 Cross-Site Scripting 問題。
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication4.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label0" runat="server"></asp:Label><br />
<asp:Label ID="Label1" runat="server"></asp:Label><br />
<asp:Label ID="Label2" runat="server"></asp:Label><br />
<asp:Label ID="Label3" runat="server"></asp:Label><br />
<asp:Label ID="Label4" runat="server"></asp:Label><br />
<asp:Label ID="Label5" runat="server"></asp:Label><br />
<asp:Label ID="Label6" runat="server"></asp:Label><br />
<asp:Label ID="Label7" runat="server"></asp:Label><br />
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</div>
</form>
</body>
</html>
|
Default.aspx.cs
using Ganss.XSS;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication4
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
// NuGet 要安裝 AntiXSS 4.3.0
string testString = "<b>Test</b><script>alert(1);</script>123'" + Request.QueryString["XSS"];
Label0.Text = testString;
Label1.Text = Microsoft.Security.Application.Encoder.HtmlEncode(testString);
Label2.Text = Server.HtmlEncode(testString);
Label3.Text = System.Web.Security.AntiXss.AntiXssEncoder.HtmlEncode(testString, true);
Label4.Text = System.Web.Security.AntiXss.AntiXssEncoder.HtmlEncode(testString, false);
Label5.Text = HttpUtility.HtmlEncode(testString);
Label6.Text = System.Net.WebUtility.HtmlEncode(testString);
// NuGet 要安裝 HtmlSanitizer
var sanitizer = new HtmlSanitizer();
Label7.Text = sanitizer.Sanitize(testString);
}
}
} |
(下圖) testString 有 XSS 問題,Label0 沒有處理就輸出,彈出了視窗,Fortify SCA也掃出有問題。
********************************************************************************
測試 含空白字串、日期資料
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /><br />
<asp:Literal ID="Literal1" runat="server"></asp:Literal><br />
<asp:Literal ID="Literal2" runat="server"></asp:Literal><br />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br />
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label><br />
</form>
</body>
</html>
|
注意,HtmlSanitizer 8.x 使用的是 using Ganss.Xss; 不是 using Ganss.XSS; (大小寫差異)
Default.aspx.cs
using Ganss.Xss;
using System; namespace WebApplication1
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
//string testString = "<b>Test</b><script>alert(1);</script>123'" + Request.QueryString["XSS"];
string testString = "<b>Test</b> " + DateTime.Now.ToString();
// NuGet 要安裝 HtmlSanitizer
var sanitizer = new HtmlSanitizer();
Literal1.Text = testString;
Literal1.Text = sanitizer.Sanitize(testString);
Label1.Text = testString;
Label2.Text = sanitizer.Sanitize(testString);
}
}
}
|
********************************************************************************
APS.NET WebForm 程式<asp:Label ID="lb_GroupName" runat="server" Text='<%# Eval("GroupName") %>' /> 如何用using Ganss.Xss; 和sanitizer.Sanitize 改寫,避免 XSS 問題?
ChatGPT
首先,請確保您已將 Ganss.Xss 庫新增至您的專案。 您可以透過 NuGet 套件管理器來安裝該程式庫。
Default.aspx
<asp:Label ID="lb_GroupName" runat="server" Text='<%# Sanitizer_Sanitize(Eval("GroupName").ToString()) %>' />
|
Default.aspx.cs
using Ganss.Xss;
protected string Sanitizer_Sanitize(string input) {
var sanitizer = new HtmlSanitizer();
return sanitizer.Sanitize(input);
}
|
或
Common.cs
public static string MyAntiXssFilter(object inputObject)
{
// 注意,MyAntiXssFilter 參數若為網址,& 會變成 & ,無法傳1個以上參數,改成
string inputStr = "";
if (inputObject != null)
{
inputStr = inputObject.ToString();
}
var sanitizer = new HtmlSanitizer();
sanitizer.AllowedAttributes.Add("class");
sanitizer.AllowedAttributes.Add("id");
// 允許 <a href="mailto:"
sanitizer.AllowedSchemes.Add("mailto");
// 沒用; 若處理網址, & 會變成 &
//sanitizer.AllowedAttributes.Add("&");
var sanitized = sanitizer.Sanitize(inputStr);
sanitized = sanitized.Replace("&", "&");
return sanitized;
}
|
Default.aspx
<asp:Label ID="lb_GroupName" runat="server" Text='<%# Common.MyAntiXssFilter(Eval("GroupName").ToString()) %>' />
|
注意 Eval("GroupName") 改成 Common.MyAntiXssFilter(Eval("GroupName")),後面兩個括弧若少了一個,Compile 時不會有錯誤或警告,除非目前在 .aspx 網頁上,才會有一點警告
因為 MyAntiXssFilter 傳入是 object,傳出已經是 string,所以可以不用 ToString()。
********************************************************************************
2024-02-27
boxList.DataSource = En.Sys.Where(s => s.Id == id && s.Level == "A")
.Select(t => new { v1 = HttpUtility.HtmlEncode(t.Name), v2 = HttpUtility.HtmlEncode(t.Id) })
.ToList();
使用 HttpUtility.HtmlEncode 失敗
********************************************************************************
結論
- HtmlEncode 把 HTML Tag 全部都編碼了,HtmlSanitizer 保留部分安全的 HTML Tag不做編碼,避免 XSS 問題。
- 如果 testString 你確認沒有 HTML Tag,兩者都可用。
- 如果 testString 不應該有 HTML Tag,用 HtmlEncode。(更好做法是把 HTML Tag移除,例如 HTML Agility Pack,https://www.nuget.org/packages/HtmlAgilityPack/
- 如果 testString 有 HTML Tag,只是要處理有 XSS 問題的,用 HtmlSanitizer。
(完)
相關
探討 .NET HtmlEncode 解決方案之間的比較
https://www.thinkinmd.com/post/2020/07/25/discuss-dotnet-htmlencode-solutions-and-compare/#-htmlencode
【HTML】AntiXss.HtmlEncode vs AntiXss.GetSafeHtmlFragment
https://www.796t.com/post/MXliOWs=.html