Repository navigation
This hotfix release closes a way around RequireAuthorization() on the viewer API and updates a vulnerable dependency of the rendering engine. Upgrading is strongly recommended for every application that restricts access to the viewer, and for every application that uses GroupDocs.Viewer.UI.SelfHost.Api. The rendering engine stays at GroupDocs.Viewer 26.9.0.
🔒 Security fixes
Update all GroupDocs.Viewer.UI.* packages to 26.9.1:
| Issue | Affected applications | Fixed in |
|---|---|---|
The viewer API could be reached through conventional routes of the application, without the conventions added to MapGroupDocsViewerApi, such as RequireAuthorization() (#117) |
applications that restrict access to the viewer API and also map conventional controller routes, for example with MapDefaultControllerRoute() or MapControllerRoute(...) |
GroupDocs.Viewer.UI.Api |
System.Security.Cryptography.Pkcs 8.0.0 has two denial of service vulnerabilities (CVE-2026-84008, CVE-2026-70162) |
AddGroupDocsViewerSelfHostApi(...) |
GroupDocs.Viewer.UI.SelfHost.Api |
Only MapGroupDocsViewerApi routes reach the viewer API
The viewer controller has no attribute routes, so ASP.NET Core applied every conventional route of the application to it. For example, the default route {controller=Home}/{action=Index}/{id?} from MapDefaultControllerRoute() created /Viewer/GetPdf, /Viewer/ViewData, and an endpoint for every other API action. Conventions added to MapGroupDocsViewerApi apply only to the routes under ApiPath, so anonymous users could read documents through these endpoints even when the application followed Restrict access.
The viewer controller now requires the route value groupdocs-viewer-api=true (ApiNames.ROUTE_VALUE_KEY and ApiNames.ROUTE_VALUE). Only the routes that MapGroupDocsViewerApi maps provide it, so other conventional routes of the application no longer reach the controller and return 404 Not Found. The URLs under ApiPath don't change, and the viewer UI works as before.
To check whether an application on 26.9.0 or earlier is affected, open /Viewer/GetPdf?file=<document> signed out. If the response is the PDF file, the viewer API can be reached around its conventions.
System.Security.Cryptography.Pkcs updated to patched versions
GroupDocs.Viewer 26.9.0 depends on System.Security.Cryptography.Pkcs 8.0.0. Microsoft published two vulnerabilities in this version on October 13, 2026:
- CVE-2026-84008, high severity:
SignedCms.CheckSignaturecan parse attacker-controlled X.509 data again and again, which exhausts the CPU. All platforms. - CVE-2026-70162, moderate severity:
EnvelopedCms.Decodecan do quadratic work on attacker-supplied CMS or PKCS#7 attributes, which exhausts the CPU. Windows only.
GroupDocs.Viewer.UI.SelfHost.Api now references the patched versions: 8.0.2 on .NET 6 and .NET 8, and 10.0.13 on .NET 10. NuGet no longer reports the NU1902 and NU1903 warnings for this package.
Microsoft also recommends installing the latest .NET update and restarting your applications. Self-contained deployments must be rebuilt and redeployed.
If you can't upgrade right away
-
Require signed-in users for every endpoint without authorization metadata with a fallback policy. The endpoints that conventional routes create for the viewer controller have no authorization metadata, so the fallback policy applies to them:
builder.Services.AddAuthorization(options => options.FallbackPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
The fallback policy requires a signed-in user only. If the viewer API uses a stricter policy, for example a role, any signed-in user can still reach these endpoints. The fallback policy also applies to your own endpoints, so mark the public ones with
[AllowAnonymous]or.AllowAnonymous(). -
Reference the patched
System.Security.Cryptography.Pkcsfrom your application: version8.0.2on .NET 6 and .NET 8, or10.0.13on .NET 10.
⚠️ Behavior changes
Applications that call the viewer API only through the URLs under ApiPath need no changes. The viewer UI and all samples in the repository work this way. Otherwise, check this table:
| Your application | After the upgrade | What to do |
|---|---|---|
Calls the API through a conventional route of the application, for example /Viewer/GetPdf or /Viewer/ViewData |
404 Not Found |
Call the URLs under ApiPath instead, for example /viewer-api/get-pdf or /viewer-api/view-data |
| Maps its own conventional route to the viewer controller | 404 Not Found |
Use MapGroupDocsViewerApi with ApiPath, or add the route value to the route defaults, see below |
Reaches a subclass of ViewerController through a conventional route |
404 Not Found |
Give the subclass an attribute route, [Route("...")], or add the route value to the route defaults. Attribute routes are not affected |
Generates API links with Url.Action(...) or LinkGenerator.GetPathByAction(...) |
null, or a link such as /Viewer/GetPdf that returns 404 Not Found |
Generate the links by route name, see below |
To keep your own conventional route to the viewer controller, add the route value to its defaults. Conventions on MapGroupDocsViewerApi, such as RequireAuthorization(), don't apply to your route, so add them to it as well:
using GroupDocs.Viewer.UI.Api;
using Microsoft.AspNetCore.Routing;
app.MapControllerRoute("my-viewer-api", "my-viewer-api/{action}",
new RouteValueDictionary
{
["controller"] = ApiNames.CONTROLLER_NAME,
[ApiNames.ROUTE_VALUE_KEY] = ApiNames.ROUTE_VALUE,
}).RequireAuthorization();To generate a link to an API method, use its route name. The route names are the API method names in ApiNames. This works in 26.9.1 and in earlier versions:
var pdfUrl = Url.RouteUrl(ApiNames.API_METHOD_GET_PDF, new { file = "sample.docx" });
// /viewer-api/get-pdf?file=sample.docxThe same notes are in the Upgrade notes section of the README.
🛠️ Other changes
New sample: authorization
The new GroupDocs.Viewer.UI.Sample.Authorization sample shows how to require signed-in users in an ASP.NET Core MVC application:
- Cookie authentication with two demo accounts,
viewerwith theviewerrole andguestwithout roles. - One role-based policy applied to both the viewer UI and the viewer API with
RequireAuthorization("ViewerUsers"). - The MVC default route next to the viewer, which no longer reaches the viewer API.
401and403status codes instead of redirects to the sign-in page for viewer API requests.
Use the same policy for the UI and the API. The viewer shows its password prompt for any 403 Forbidden response from the API, so a user who is denied by the API but allowed into the UI sees a password prompt instead of an access error.
GroupDocs.Viewer.UI no longer references Microsoft.Extensions.Http
The package referenced Microsoft.Extensions.Http without using it. The ASP.NET Core shared framework already provides this assembly on every supported target framework, so no action is needed.
GroupDocs.Viewer.UI.SelfHost.Api.CrossPlatform is not updated
26.8.0 remains the final release of the deprecated package, and a project that references only this package keeps getting GroupDocs.Viewer.UI.SelfHost.Api 26.8.0 without the fixes in 26.9.0 and 26.9.1. Replace the reference, no code changes are needed:
-<PackageReference Include="GroupDocs.Viewer.UI.SelfHost.Api.CrossPlatform" Version="26.8.0" />
+<PackageReference Include="GroupDocs.Viewer.UI.SelfHost.Api" Version="26.9.1" />📦 Packages
All GroupDocs.Viewer.UI packages are available on NuGet at version 26.9.1:
- GroupDocs.Viewer.UI
- GroupDocs.Viewer.UI.Api
- GroupDocs.Viewer.UI.Api.AwsS3.Storage
- GroupDocs.Viewer.UI.Api.AzureBlob.Storage
- GroupDocs.Viewer.UI.Api.Cloud.Storage
- GroupDocs.Viewer.UI.Api.Distributed.Cache
- GroupDocs.Viewer.UI.Api.InMemory.Cache
- GroupDocs.Viewer.UI.Api.Local.Cache
- GroupDocs.Viewer.UI.Api.Local.Storage
- GroupDocs.Viewer.UI.Cloud.Api
- GroupDocs.Viewer.UI.Core
- GroupDocs.Viewer.UI.SelfHost.Api
Thank you for using GroupDocs.Viewer.UI! If you encounter any issues or have suggestions, please don't hesitate to provide feedback here on GitHub or at our Free Support Forum.