Open Closed

Security Finding in ABP v9.2.4: Unauthenticated Tenant Enumeration via /by-name and /by-id Endpoints #10725


User avatar
0
murat.kebabci created

We have identified a high-severity security finding (CWE-204: Observable Response Discrepancy) during a recent penetration test regarding the default tenant lookup endpoints in the ABP framework.

Affected Endpoints:

  • GET /api/abp/multi-tenancy/tenants/by-name/{name}
  • GET /api/abp/multi-tenancy/tenants/by-id/{guid}

Issue Details: Both lookups return existence-oracle responses anonymously. There is no rate limiting in place. The tenant UUIDs feed several other tenant-aware unauthenticated endpoints, allowing an attacker to enumerate valid tenants on the system.

Requested Assistance & Remediation Guidance: The SPA does not require anonymous tenant lookup once the login URL accepts a tenant query parameter. Can you provide the recommended approach to either:

  1. Enforce the MultiTenancy permission on both endpoints to prevent unauthenticated access.
  2. Completely remove or disable these endpoints from the public route in our current ABP version.
Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

1 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Hi,

    Thanks for the detailed write-up. Quick confirmation first: I checked the v9.2.4 source and the current 10.x code path — the controller and the underlying app service are unchanged, so what you reported is by design rather than a regression.

    The reason both endpoints are anonymous is that the framework's RemoteTenantStore (used by MVC, Blazor, MAUI and the Angular tenant-box) needs to resolve a tenant by name or id before the user logs in — it has nothing to authenticate with at that point. So we can't simply add [Authorize] to the default endpoints without breaking those clients.

    For your case, since the Angular SPA already gets the tenant from the login URL query parameter, you can replace the IAbpTenantAppService implementation in your *.HttpApi.Host (and the AuthServer host too, if it exposes the same routes in your tiered setup) so both methods return a constant "not found" response. That removes the existence oracle without breaking the URL contract:

    using System;
    using System.Threading.Tasks;
    using Volo.Abp.Application.Services;
    using Volo.Abp.AspNetCore.Mvc.MultiTenancy;
    using Volo.Abp.DependencyInjection;
    
    namespace MyCompanyName.MyProjectName;
    
    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(IAbpTenantAppService))]
    public class SealedAbpTenantAppService : ApplicationService, IAbpTenantAppService
    {
        public virtual Task<FindTenantResultDto> FindTenantByNameAsync(string name)
        {
            return Task.FromResult(new FindTenantResultDto { Success = false });
        }
    
        public virtual Task<FindTenantResultDto> FindTenantByIdAsync(Guid id)
        {
            return Task.FromResult(new FindTenantResultDto { Success = false });
        }
    }
    

    With this in place, both tenants/by-name/{name} and tenants/by-id/{id} return the same payload for every input:

    {"success":false,"tenantId":null,"name":null,"normalizedName":null,"isActive":false}
    

    So the response no longer differs for existing vs non-existing tenants and the enumeration is gone. I verified this on a fresh 10.x app with a seeded tenant — same bytes in both cases.

    For the missing rate limit, we'd rather not bake one into the framework either, since the right threshold depends on your deployment. The simplest options are ASP.NET Core's built-in RateLimiter middleware scoped to /api/abp/multi-tenancy/tenants/*, or a rule at your reverse proxy (YARP / nginx / ingress). Either works alongside the override above.

    Thanks

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on September 16, 2026, 14:50
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.