2024年3月11日 星期一

[研究]Fotify SCA 報告 FileUpload1.SaveAs(openFilename); 有 Often Misused: File Upload 問題

[研究]Fotify SCA 報告 FileUpload1.SaveAs(openFilename); 有 Often Misused: File Upload 問題

2024-03-11

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19

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

【Fortify SCA】Details

Abstract:

在 Webform1.aspx.cs 的 Button1_Click() 函數呼叫第 251 行的 SaveAs()。允許使用者上傳檔案可能會使攻擊者在伺服器執行已插入的危險內容或惡意程式碼。

Explanation:

不論撰寫程式所使用的語言為何,毀壞性最大的攻擊通常都包含了遠端程式碼的執行,攻擊者可藉此在程式的上下文環境中成功的執行惡意程式碼。若攻擊者能夠上傳檔案至一個可從網路存取的目錄,並將這些檔案傳遞至程式碼解譯器 (例如 JSP/ASPX/PHP),則他們可能會造成這些檔案內包含的惡意程式碼在伺服器上執行。

下列程式碼收到上傳檔案並將其指派給 posted 物件。FileUpload 屬於 System.Web.UI.HtmlControls.HtmlInputFile 類型。

範例:

HttpPostedFile posted = FileUpload.PostedFile;

即使程式將上傳的檔案儲存於無法從 Web 存取的目錄下,攻擊者仍然可能透過向伺服器環境引入惡意內容中來發動其他攻擊。若程式容易有 Path Manipulation、Command Injection 或 Dangerous File Inclusion 的弱點,則攻擊者可能會上傳含有惡意內容的檔案並利用另一項弱點,使程式讀取或執行該檔。

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

【Fortify SCA】Recommendations:

在可以避免的情況下,請勿接受附加檔案。如果程式必須接受附加檔案,則應只接受程式預期的特定內容類型,以阻止攻擊者提供惡意內容。大部分依賴上傳內容的攻擊都需要攻擊者能夠提供他們所選擇的內容。限制程式所接受的內容可大幅減少發生攻擊的可能性。請檢查檔案名稱、副檔名及檔案內容,以確定他們皆符合預期並可供應用程式使用。讓攻擊者難以確定上傳檔案的名稱及位置。此類解決方法通常因程式而異,且在以下幾個方面各不相同:將上傳的案檔儲存在目錄中 (目錄名稱是在程式初始化時透過強大的隨機值產生的)、為每個上傳的檔案指定隨機的名稱,以及利用資料庫中的項目追蹤這些檔案 [1]。

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

User

ASP.NET, WebForm, Fotify SCA 報告 FileUpload1.SaveAs(openFilename); 有 Often Misused File Upload 問題,在可以避免的情況下,請勿接受附加檔案。如果程式必須接受附加檔案,則應只接受程式預期的特定內容類型,以阻止攻擊者提供惡意內容。但程式有檢查

string ext = System.IO.Path.GetExtension(FileUpload1.FileName).ToLower();
if (!(ext == ".xlsx"))
{
return;
}

請問如何避免此問題?

ChatGPT

要避免常見的檔案上傳問題,可以實施以下措施:

  • 驗證檔案類型: 像你在程式碼中所做的那樣,驗證檔案的副檔名是一個好的開始,但不足以防止所有的攻擊。攻擊者可以輕易地將檔案重新命名,讓其看起來像受信任的類型。因此,最好的方式是透過檔案的真實內容來驗證檔案類型,而不僅僅是依靠副檔名。
  • 限制檔案大小: 限制上傳檔案的大小,這樣可以防止攻擊者上傳過大的檔案,消耗伺服器資源或造成拒絕服務 (DoS) 攻擊。
  • 掃描檔案內容: 在上傳檔案後,進行病毒掃描或掃描檔案內容,以確保它們是安全的。
  • 存儲檔案在安全位置: 確保上傳的檔案存儲在伺服器上的安全位置,避免攻擊者通過檔案上傳來訪問敏感資訊或執行惡意程式碼。
  • 限制上傳路徑: 確保只有授權的使用者可以上傳檔案,並且檔案只能上傳到受信任的路徑。

總的來說,最佳做法是結合多個安全措施,包括驗證、限制、掃描和安全存儲,以最大程度地減少檔案上傳所帶來的風險。

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

【實際測試】

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:FileUpload ID="FileUpload1" runat="server" accept=".xlsx" /><br />
        <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
    </form>
</body>
</html>

Default.aspx.cs

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 ext = System.IO.Path.GetExtension(FileUpload1.FileName).ToLower();
            if (!(ext == ".xlsx"))
            {
                return;
            }
            string fileName = "ABC" + ext;
            if (FileUpload1.FileBytes.Length > 10 * 1024 * 1024)
            {
                return;
            }
            FileUpload1.SaveAs(fileName);
        }
    }
}

前端也加檢查,後端多加上檔案大小檢查,結果仍不行

隨機檔案名稱也測試過,失敗。

string randomFileName = Path.GetRandomFileName();

FileUpload1.SaveAs(randomFileName);

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

待研究。

(待續)

相關

沒有留言:

張貼留言