New to Telerik UI for ASP.NET AJAXStart a free 30-day trial

Insufficient Entropy Vulnerability (2878)

Updated on Feb 25, 2026

Description

February 2026 - CVE-2026-2878

  • Progress® Telerik® UI for AJAX 2026 Q1 (2026.1.211) or earlier.

What Are the Impacts

In Progress® Telerik® UI for AJAX, versions prior to 2026.1.225, an insufficient entropy vulnerability exists in RadAsyncUpload, where a predictable temporary identifier, based on timestamp and filename, can enable collisions and file content tampering.

Issue

  • CWE-331: Insufficient Entropy
  • CAPEC-149: Explore for Predictable Temporary File Names => CAPEC-26: Leveraging Race Conditions

Solution

We have addressed the issue and the Progress Telerik team strongly recommends performing an upgrade to the latest version listed in the table below.

Current VersionUpdate to
>= v2011.2.712 && <= 2026.1.211 (2026 Q1)>= 2026.1.225 (2026 Q1 SP1)

Follow the update instructions for precise instructions. All customers who have a license for UI for AJAX can access the downloads here Product Downloads | Your Account.

Mitigation

If you are unable to upgrade to a product version which contains the fix (2026.1.225 [2026 Q1 SP1] or later), there are two ways mitigate the issue. Choose the option that best appropriate for your scenario.

Option 1. Per-Session Temporary Folder Isolation

This approach assigns each user session a unique, unpredictable temporary upload folder, thus an attacker cannot exploit the collision because they cannot determine the victim's temporary folder path.

Important: Do not set the TargetFolder property in the markup when using this approach. Use file.SaveAs() in the code-behind instead. Setting both TargetFolder and calling SaveAs() will result in a FileNotFoundException because the control moves the file to TargetFolder before your code executes.

  1. In the code-behind of the page(s) that use RadAsyncUpload, set the TemporaryFolder dynamically in Page_Init:

    C#
    using System;
    using System.IO;
    using Telerik.Web.UI;
    
    ...
    
    protected void Page_Init(object sender, EventArgs e)
    {
        if (Session["RadUploadTempFolder"] == null)
        {
            Session["RadUploadTempFolder"] = "~/App_Data/RadUploadTemp/"
                + Guid.NewGuid().ToString("N").Substring(0, 12) + "/";
        }
    
        string sessionFolder = (string)Session["RadUploadTempFolder"];
    
        // Ensure the session-specific folder exists before assigning it,
        // otherwise the control's permission check will throw.
        string physicalPath = Server.MapPath(sessionFolder);
        if (!Directory.Exists(physicalPath))
            Directory.CreateDirectory(physicalPath);
    
        RadAsyncUpload1.TemporaryFolder = sessionFolder;
    }
    VB
    Imports System
    Imports System.IO
    Imports Telerik.Web.UI
    
    ...
    
    Protected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Init
        If Session("RadUploadTempFolder") Is Nothing Then
            Session("RadUploadTempFolder") = "~/App_Data/RadUploadTemp/" _
                & Guid.NewGuid().ToString("N").Substring(0, 12) & "/"
        End If
    
        Dim sessionFolder As String = CStr(Session("RadUploadTempFolder"))
    
        ' Ensure the session-specific folder exists before assigning it,
        ' otherwise the control's permission check will throw.
        Dim physicalPath As String = Server.MapPath(sessionFolder)
        If Not Directory.Exists(physicalPath) Then
            Directory.CreateDirectory(physicalPath)
        End If
    
        RadAsyncUpload1.TemporaryFolder = sessionFolder
    End Sub
  2. Ensure that the TargetFolder property is not set in the markup and save files manually:

    xml
    <telerik:RadAsyncUpload runat="server" ID="RadAsyncUpload1" />
    
    <asp:Button ID="btnSubmit" Text="Submit" runat="server" OnClick="btnSubmit_Click" />
    C#
    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        foreach (UploadedFile file in RadAsyncUpload1.UploadedFiles)
        {
            string targetPath = Server.MapPath("~/App_Data/RadUploadTarget/");
            if (!System.IO.Directory.Exists(targetPath))
                System.IO.Directory.CreateDirectory(targetPath);
    
            file.SaveAs(System.IO.Path.Combine(targetPath, file.GetName()), true);
        }
    }
    VB
    Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As EventArgs)
        For Each file As UploadedFile In RadAsyncUpload1.UploadedFiles
            Dim targetPath As String = Server.MapPath("~/App_Data/RadUploadTarget/")
            If Not Directory.Exists(targetPath) Then
                Directory.CreateDirectory(targetPath)
            End If
    
            file.SaveAs(Path.Combine(targetPath, file.GetName()), True)
        Next
    End Sub

How It Works

The original vulnerability relies on the attacker being able to predict the full path to the victim's temporary file: <known temp folder>/<predictable UploadID>. With per-session folders, the path becomes <known temp folder>/<unpredictable session subfolder>. The 12-character hex subfolder name (48 bits of entropy, ~281 trillion combinations) is generated server-side using Guid.NewGuid() and is never exposed to the client in any HTTP response, header, or cookie.

Considerations

  • Cleanup: Telerik's built-in cache-based cleanup automatically deletes individual temporary files when they expire (default: 4 hours, configurable via TemporaryFileExpiration). However, it does not remove the session-specific subdirectories. Over time, empty folders will accumulate. Implement a periodic cleanup using a background timer in Global.asax or a scheduled task to remove stale subdirectories:

    C#
    using System;
    using System.IO;
    
    ...
    
    // In Global.asax
    private static System.Threading.Timer _cleanupTimer;
    private static string _tempRoot;
    
    void Application_Start(object sender, EventArgs e)
    {
        _tempRoot = Server.MapPath("~/App_Data/RadUploadTemp");
    
        // Run cleanup once at startup, then every 4 hours
        CleanupStaleTempFolders(null);
    
        _cleanupTimer = new System.Threading.Timer(CleanupStaleTempFolders, null, 
            TimeSpan.FromHours(4), TimeSpan.FromHours(4));
    }
    
    private static void CleanupStaleTempFolders(object state)
    {
        if (!Directory.Exists(_tempRoot)) return;
    
        foreach (string dir in Directory.GetDirectories(_tempRoot))
        {
            if (Directory.GetCreationTimeUtc(dir) < DateTime.UtcNow.AddHours(-24))
            {
                try { Directory.Delete(dir, true); } catch { }
            }
        }
    }
    
    void Application_End(object sender, EventArgs e)
    {
        if (_cleanupTimer != null)
        {
            _cleanupTimer.Dispose();
            _cleanupTimer = null;
        }
    }
  • Folder creation: The session-specific folder must exist before RadAsyncUpload renders, otherwise the control's built-in permission check (TestTemporaryFolderPermissions) will throw a DirectoryNotFoundException. This is why Directory.CreateDirectory() is called in Page_Init before setting TemporaryFolder.

  • TargetFolder conflict: Do not combine this approach with the TargetFolder property. When TargetFolder is set, the control automatically moves uploaded files out of the temporary folder during postback processing — before any FileUploaded event or button click handler executes. This causes file.SaveAs() to fail with a FileNotFoundException.

  • ASP.NET process permissions: Ensure the ASP.NET worker process has write permissions to create subdirectories under the configured parent folder (App_Data/RadUploadTemp by default).

  • MAX_PATH: The per-session subfolder adds 13 characters (12-character hex name + path separator) to the temporary file path, therefore deeply nested base paths combined with long filenames may still approach the Windows MAX_PATH limit of 260 characters. Verify that your configured TemporaryFolder base path leaves sufficient headroom.

Option 2. Disable the AsyncUpload Handler

If your application does not use RadAsyncUpload (or RadCloudUpload), you can eliminate the vulnerability entirely by disabling the upload handler. Add the following key to the <appSettings> section of your web.config:

xml
<appSettings>
  <add key="Telerik.Web.DisableAsyncUploadHandler" value="true" />
</appSettings>

When set to true, the handler returns HTTP 404 for all upload requests, completely removing the attack surface.

Considerations

  • This disables all RadAsyncUpload and RadCloudUpload functionality across the entire application. Do not use this option if any page relies on asynchronous file uploads.
  • Other Telerik handler functionality (script resources, dialogs, etc.) served by Telerik.Web.UI.WebResource.axd is not affected — only upload requests (?type=rau) are blocked.

Notes

  • If you have any questions or concerns related to this issue, open a new Technical Support case in Your Account | Support Center. Technical Support is available to customers with an active support plan.
  • We would like to thank the team at the Monetary Authority of Singapore for their responsible disclosure and cooperation.

External References

CVE-2026-2878 (MEDIUM)

CVSS: 5.3

In Progress® Telerik® UI for AJAX, versions prior to 2026.1.225, an insufficient entropy vulnerability exists in RadAsyncUpload, where a predictable temporary identifier, based on timestamp and filename, can enable collisions and file content tampering.

Discoverer Credit: Monetary Authority of Singapore