2024年2月26日 星期一

[研究][ASP.NET][C#][WebForm]Server-Side Request Forgery (SSRF) 解決

[研究][ASP.NET][C#][WebForm]Server-Side Request Forgery (SSRF) 解決

2024-02-26

【問題】

Fortify SCA 報告有伺服器端請求偽造 (Server-side request forgery, SSRF)問題

HttpWebRequest req = (HttpWebRequest)WebRequest.Create
    ("https://www.google.com/recaptcha/api/siteverify?secret=6LemXqE&response=" + Response); 

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);  

https://vulncat.fortify.com/zh-tw/detail?id=desc.dataflow.java.server_side_request_forgery#C%23%2FVB.NET%2FASP.NET

Fortify SCA 報告

Abstract:

Create() 利用使用者控制的資料啟動與第三方系統的網路連線以存取資源 URI。由於要求源自應用程式伺服器內部 IP 位址,因而攻擊者可能代表應用程式伺服器利用此弱點傳送要求。

Explanation:

當攻擊者可以影響應用程式伺服器建立的網路連線時,就會發生 Server-Side Request Forgery。網路連線來自應用程式伺服器的內部 IP,因而攻擊者可以使用此連線略過網路控制措施,並掃描或攻擊原本未暴露的內部資源。

Recommendations:

切勿根據使用者控制的資料建立網路連線,並確保請求傳送至預期的目的地。如果建立目的地 URI 需要使用者資料,請使用間接方法:建立允許使用者指定的合法資源名稱的清單,並只允許使用者從清單中選取。使用此方法,使用者就不能直接輸入來指定資源名稱。

但在某些情況下,這種方法是不切實際的,因為這樣一份合法資源名稱太過於龐大或是太難以維護。在這些情況下,程式設計師通常會實作拒絕清單。在使用輸入資料前,拒絕清單會選擇性的拒絕或避開可能有危險的字元。不過,任何此類不安全字元清單可能都不完整,並且幾乎肯定會過期。一個更好的方法是建立字元清單。此清單會列出允許出現於資源名稱中的字元,並僅接受由核准集中的字元組成的輸入。

另外,如果需要,請確保使用者輸入僅用於指定目標系統上的資源,而 URI 架構、主機及連接埠由應用程式控制。這樣會大大減輕攻擊者可能造成的損害。

References:

[1] Alexander Polyakov, SSRF vs. Business critical applications, BlackHat 2012, http://media.blackhat.com/bh-us-12/Briefings/Polyakov/BH_US_12_Polyakov_SSRF_Business_Slides.pdf

[2] SSRF bible. Cheatsheet, ONSec Labs, https://docs.google.com/document/d/1v1TkWZtrhzRLy0bYXBcdLUedXGb9njTNIJXa3u9akHM/edit

********************************************************************************

【參考】

ASP.NET WebForm, 如何解決 HttpWebRequest req = (HttpWebRequest)WebRequest.Create 的 Server-side request forgery 問題

ChatGPT

要解決ASP.NET WebForms中的伺服器端請求偽造(Server-side request forgery,SSRF)問題,您可以採取下列措施:

1.輸入驗證和過濾:在使用使用者提供的URL之前,請務必進行嚴格的輸入驗證和過濾。 確保URL是有效的,且只包含您允許的協定和網域。

string userUrl = userInputTextBox.Text;
if (Uri.TryCreate(userUrl, UriKind.Absolute, out Uri validatedUri))
{
     if (validatedUri.Scheme == Uri.UriSchemeHttp || validatedUri.Scheme == Uri.UriSchemeHttps)
     {
         // 繼續處理請求
         HttpWebRequest req = (HttpWebRequest)WebRequest.Create(validatedUri);
         // 執行請求並處理回應
     }
     else
     {
         // 拒絕非HTTP/HTTPS協定的URL
         // 可以記錄或回報非法URL的嘗試
     }
}
else
{
     // 拒絕無效的URL
     // 可以記錄或回報無效URL的嘗試
}

2.白名單驗證:限制應用程式可以存取的URL範圍,只允許存取您信任的網域或URL。 這可以透過配置一個白名單列表來實現,只有列表中的URL才能被應用程式存取。

3,安全性配置:確保應用程式的伺服器和網路配置是安全的,防止應用程式發出惡意或未經授權的請求。 例如,防火牆和網路隔離可以幫助限制對不信任資源的存取。

4.權限控制:在可能的情況下,使用應用程式的身份驗證和授權機制來限制對敏感資源的存取。 確保只有經過身份驗證和授權的使用者才能執行敏感操作。

5.更新和監控:定期更新應用程式和相關的程式庫,以修復已知的安全漏洞,並監視應用程式的行為,以偵測潛在的惡意活動。

透過採取這些措施,您可以有效地減少ASP.NET WebForms應用程式中的伺服器端請求偽造問題的風險。

********************************************************************************

【解決】

Default.aspx.cs

string Response = Request["g-recaptcha-response"];
bool Valid = false;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create
("https://www.google.com/recaptcha/api/siteverify?secret=6Ldw&response=" + Response);
try
{
    //Google recaptcha Response
    using (WebResponse wResponse = req.GetResponse())
    {

        using (StreamReader readStream = new StreamReader(wResponse.GetResponseStream()))
        {
            string jsonResponse = readStream.ReadToEnd();

            JavaScriptSerializer js = new JavaScriptSerializer();
            MyObject data = js.Deserialize<MyObject>(jsonResponse);// Deserialize Json

            Valid = Convert.ToBoolean(data.success);
        }
    }

    return Valid;
}
catch (WebException ex)
{
    throw ex;
}

改為

Default.aspx.cs


// Fortify SCA 報告 HttpWebRequest req = (HttpWebRequest)WebRequest.Create 有 Server-Side Request Forgery (SSRF) 問題
#region === 處理 SSRF ===
//HttpWebRequest req = (HttpWebRequest)WebRequest.Create
//("https://www.google.com/recaptcha/api/siteverify?secret=6LdwoDsjAAAAAN0pQmRJEW0dtD0vOe6XTV6obAk0&response=" + Response);

HttpWebRequest req = null;
string googleReCaptchaUrl = "https://www.google.com/recaptcha/api/siteverify?secret=6Ldw&response=" + Response;
if (Uri.TryCreate(googleReCaptchaUrl, UriKind.Absolute, out Uri validatedUri))
{
    if (validatedUri.Scheme == Uri.UriSchemeHttp || validatedUri.Scheme == Uri.UriSchemeHttps)
    {
        // 繼續處理請求
        //HttpWebRequest req = (HttpWebRequest)WebRequest.Create(validatedUri);
        req = (HttpWebRequest)WebRequest.Create(validatedUri);
        // 執行請求並處理回應
    }
    else
    {
        Label_MSG1.Text = "拒絕非HTTP/HTTPS協定的URL";
        // 拒絕非HTTP/HTTPS協定的URL
        // 可以記錄或回報非法URL的嘗試
    }
}
else
{
    // 拒絕無效的URL
    Label_MSG1.Text = "拒絕無效的URL";
    // 可以記錄或回報無效URL的嘗試
}
#endregion === 處理 SSRF ===

try
{
    //Google recaptcha Response
    using (WebResponse wResponse = req.GetResponse())
    {

        using (StreamReader readStream = new StreamReader(wResponse.GetResponseStream()))
        {
            string jsonResponse = readStream.ReadToEnd();

            JavaScriptSerializer js = new JavaScriptSerializer();
            //MyObject data = js.Deserialize<MyObject>(jsonResponse);// Deserialize Json

            //Valid = Convert.ToBoolean(data.success);
        }
    }

    return Valid;
}
catch (WebException ex)
{
    throw ex;
}

********************************************************************************

(完)

相關

[研究]CSRF, SSRF, XSS 比較
https://shaurong.blogspot.com/2024/02/csrf-ssrf-xss.html

白名單
html - How to make a C# whitelist/BlackList - Stack Overflow
https://stackoverflow.com/questions/1442005/how-to-make-a-c-sharp-whitelist-blacklist

C# static code analysis | Vulnerability
https://rules.sonarsource.com/csharp/type/Vulnerability/RSPEC-5144

沒有留言:

張貼留言