[研究]Forify SCA 的 Open Redirect 問題(七)用HtmlSanitizer套件處理Request.Url.Query
2025-02-05
[研究]Forify SCA 的 Open Redirect 問題(一)重導 Response.Redirect() 與 Server.Transfer()
https://shaurong.blogspot.com/2021/07/aspnetfortify-sca-open-redirect.html
後來發現在某些情況下,這樣改會有問題。
[研究]Forify SCA 的 Open Redirect 問題(二)ckeditor 的 tmpFrameset.html
https://shaurong.blogspot.com/2021/07/aspnetfortify-scatmpframesethtmlopen.html
[研究]Forify SCA 的 Open Redirect 問題(三)回到上一頁按鈕、返回按鈕https://shaurong.blogspot.com/2021/08/aspnet-fortify-scaopen-redirect.html
[研究]Forify SCA 的 Open Redirect 問題(四)用 ASP.NET + JavaScript 來解決
http://shaurong.blogspot.com/2021/08/forify-sca-open-redirect-aspnet.html
[研究]Forify SCA 的 Open Redirect 問題(五)用空的函數欺騙(失敗)
https://shaurong.blogspot.com/2022/06/forify-sca-open-redirect.html
[研究]Forify SCA 的 Open Redirect 問題(六)用HtmlSanitizer套件https://shaurong.blogspot.com/2022/06/forify-sca-open-redirect-htmlsanitizer.html
[研究]Forify SCA 的 Open Redirect 問題(七)用HtmlSanitizer套件處理Request.Url.Query
https://shaurong.blogspot.com/2025/02/forify-sca-open-redirect.html
NuGet 安裝 HtmlSanitizer 套件
https://github.com/mganss/HtmlSanitizer
HtmlSanitizer 是一個 .NET 庫,用於從可能導致XSS 攻擊的構造中清除 HTML 片段和文檔。它使用AngleSharp來解析、操作和渲染 HTML 和 CSS。
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" />
<asp:Button ID="Button2" runat="server" Text="Button" OnClick="Button2_Click" />
<asp:Button ID="Button3" runat="server" Text="Button" OnClick="Button3_Click" />
<asp:Button ID="Button4" runat="server" Text="Button" OnClick="Button4_Click" />
<asp:Button ID="Button5" runat="server" Text="Button" OnClick="Button5_Click" />
</form>
</body>
</html>
|
Default.aspx.cs
using Ganss.Xss;
using System;
using System.Collections.Generic;
using System.Web;
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)
{
//解法 1:限制目標 URL
// Fortify SCA 報告 "Open Redirect" 問題
Response.Redirect("~/WebForm1.aspx" + Request.Url.Query);
}
protected void Button2_Click(object sender, EventArgs e)
{
//解法 2:檢查 returnUrl 只允許本站內頁
// Fortify SCA 報告 "Open Redirect" 問題
Response.Redirect(ResolveUrl("~/WebForm1.aspx") + HttpUtility.UrlEncode(Request.Url.Query));
}
protected void Button3_Click(object sender, EventArgs e)
{
//解法 3:強制 URL 經過白名單檢查
string returnUrl = Request.QueryString["returnUrl"];
if (!string.IsNullOrEmpty(returnUrl) && Uri.IsWellFormedUriString(returnUrl, UriKind.Relative))
{
// Fortify SCA 報告 "Open Redirect" 問題
//Response.Redirect(returnUrl);
// Fortify SCA 報告 "Open Redirect" 問題
Response.Redirect(returnUrl, false);
}
else
{
Response.Redirect("~/WebForm1.aspx");
}
}
protected void Button4_Click(object sender, EventArgs e)
{
List<string> allowedPages = new List<string> { "/Home.aspx", "/Dashboard.aspx", "/Profile.aspx" };
string returnUrl = Request.QueryString["returnUrl"];
if (!string.IsNullOrEmpty(returnUrl) && allowedPages.Contains(returnUrl))
{
// Fortify SCA 報告 "Open Redirect" 問題
//Response.Redirect(returnUrl);
// Fortify SCA 報告 "Open Redirect" 問題
// ChatGPT 認為此種方式若仍無法通過,可能是 Fortify SCA 誤報了
Response.Redirect(returnUrl,false);
}
else
{
Response.Redirect("~/WebForm1.aspx");
}
}
protected void Button5_Click(object sender, EventArgs e)
{
// Fortify SCA 沒有發現 "Open Redirect" 問題,通過了
Response.Redirect("~/WebForm1.aspx" + MyAntiXssFilter(Request.Url.Query));
}
public string MyAntiXssFilter(object inputObject)
{
string inputStr = "";
if (inputObject != null)
{
inputStr = inputObject.ToString();
}
var sanitizer = new HtmlSanitizer();
sanitizer.AllowedAttributes.Add("class");
sanitizer.AllowedAttributes.Add("id");
//sanitizer.AllowedAttributes.Add("&"); // 沒用; 若處理網址, & 會變成 &
var sanitized = sanitizer.Sanitize(inputStr);
sanitized = sanitized.Replace("&", "&");
return sanitized;
}
}
}
|
實測結果,過關。
(下圖)手動替網址加上2個或更多個參數,按下第5個按鈕
(下圖)成功轉址(完)


沒有留言:
張貼留言