Insufficient Entropy Vulnerability (2878)
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 Version | Update 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 [server-side]. Per-Session Temporary Folder Isolation
- Option 2 [disablement]. Disable the AsyncUpload Handler
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
TargetFolderproperty in the markup when using this approach. Usefile.SaveAs()in the code-behind instead. Setting bothTargetFolderand callingSaveAs()will result in aFileNotFoundExceptionbecause the control moves the file toTargetFolderbefore your code executes.
-
In the code-behind of the page(s) that use
RadAsyncUpload, set theTemporaryFolderdynamically inPage_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; }VBImports 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 -
Ensure that the
TargetFolderproperty 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); } }VBProtected 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 inGlobal.asaxor 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
RadAsyncUploadrenders, otherwise the control's built-in permission check (TestTemporaryFolderPermissions) will throw aDirectoryNotFoundException. This is whyDirectory.CreateDirectory()is called inPage_Initbefore settingTemporaryFolder. -
TargetFolder conflict: Do not combine this approach with the
TargetFolderproperty. WhenTargetFolderis set, the control automatically moves uploaded files out of the temporary folder during postback processing — before anyFileUploadedevent or button click handler executes. This causesfile.SaveAs()to fail with aFileNotFoundException. -
ASP.NET process permissions: Ensure the ASP.NET worker process has write permissions to create subdirectories under the configured parent folder (
App_Data/RadUploadTempby 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_PATHlimit of 260 characters. Verify that your configuredTemporaryFolderbase 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:
<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
RadAsyncUploadandRadCloudUploadfunctionality 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.axdis 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