2025年2月5日 星期三

[研究]Forify SCA 的 Open Redirect 問題(七)用HtmlSanitizer套件處理Request.Url.Query

[研究]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("&"); // 沒用; 若處理網址, & 會變成 &amp;
            var sanitized = sanitizer.Sanitize(inputStr);
            sanitized = sanitized.Replace("&amp;", "&");
            return sanitized;
        }
    }
}

實測結果,過關。

(下圖)手動替網址加上2個或更多個參數,按下第5個按鈕

(下圖)成功轉址

(完)

沒有留言:

張貼留言