1
votes

I have a standard ASP.NET MVC application that supports multiple tenants. The code has been in production for a number of months now, and I'm finding that at completely random intervals (cannot ever reproduce the issue), sometimes data from the wrong tenant is fetched for another tenant.

So for instance, Tenant1 logs in, but they receive a cookie back from our web app that contains information from the Tenant2 database!

My base Controller extracts the required tenant using the following code:

    protected override void Initialize(RequestContext requestContext)
    {
        string tenant = String.Empty;

        tenant = requestContext.Request.Headers["Host"].Split(':')[0];
        if (tenant.Contains(".")) tenant = tenant.Substring(0, tenant.IndexOf("."));

        base.Initialize(requestContext);
    }

This works in 99.9% of cases. So I can't imagine this being the problem. The only other place I can identify where something could go wrong is when I store values in a custom cookie. I have to use HttpContext.Current in order to access the current Request and extract the tenant.

Can anyone see anything in the above code, or in my use of HttpContext.Current that could result in the wrong tenant being extracted for any specific request?

The issue could be happening closer to the data layer, but the tenant is always passed through to the data layer in order to direct queries to the correct database, so I'm sure the wrong tenant is sometimes being returned.

Many thanks, Gary

1
How about profiling the SQL Server queries. Then identifying the DAL / Service that calls this Query. This can help trace the sourceSaravanan
Just for the record; I hope you have more checks on what tenant a user belongs to than a header variable... It sure sounds like a security hole waiting to be exploited... :)noocyte
Hi Noocyte. Do you have any pointers in that regard? How else would one determine the tenant based on the inbound URL request? And how exactly would someone be able to manipulate that?Gary

1 Answers

1
votes

This turned out to be a bug in Entity Framework. Essentially if a migration or long running task took place, caching of the connection string allowed the wrong connection to service another incoming thread!

Make sure you have updated to version 6.1.2 or higher.

Cheers, Gary