[研究]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個按鈕
(下圖)成功轉址(完)
沒有留言:
張貼留言