Skip to content

Authenticated user can request data from all tenants #653

@andre-zago

Description

@andre-zago

Hello, first of all, thank you for all the good work done with this package. I have set up a multi-database tenancy by using path identification following the steps in the stancl/tenancy docs. Everything works fine but when I was doing security tests I have noticed that since a user is authenticated, he is able to request data from all tenants (routes protected by auth:sanctum middleware).
I am using a Laravel 8 API with Laravel Sanctum. How could I prevent that? I have already tested changing the middleware to domain identification, subdomain identification but the problem persists.
I have read the docs exhaustively; I have searched in the Discord Community of the package and I cannot figure out how to avoid showing data from users in other databases.
For example, a tenant called 'foo' authenticates in its own database. If he, evil-minded, tries to request data from another tenant he can return the data from another database/ tenant by simply changing the parameters (uri) to a required known tenant id. As I understood, it can cause several security issues by exposing a potentially leakage of confidential information. Am I doing it wrong, or this is really a bug?

Here's my tenant.php file.

Route::group([
    'prefix' => '/{tenant}',
    'middleware' => [InitializeTenancyByPath::class, 'web'],
    PreventAccessFromCentralDomains::class,
], function () {
    
    Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
        return $request->user();
    });
    
    Route::post('/auth/login', [\App\Http\Controllers\Auth\LoginController::class, 'authenticate'])->name('auth.login');
});

Here's my LoginController with the "autentication function".

class LoginController extends Controller
{
    public function authenticate(Request $request)
    {
        $validation = $request->validate([
           'email' => 'required|string|email',
           'password' => 'required|string|min:8'
        ]);

        $attempt = Auth::attempt($validation);

        if ($attempt) {
            $request->session()->regenerate();
            return response()
                ->json([
                   'status' => true,
                   'user' => Auth::user(),
                ], 202);
        }

        return response()
            ->json([
                'status' => false,
                'message' => 'Credentials do not match',
            ], 401);
}

When, for example, the tenant 'foo' authenticates, if he requests the route of another tenant like 'bar' (mydomain.com/bar/user), it returns its data normally, even though that user lives on completely different databases, so I understood that since a user is logged in, he is gaining access to all tenants. Am I wrong? Am I doing something wrong? How can I prevent that?

My Setup

  • Laravel Framework 8.41.0
  • Laravel Sanctum 2.11
  • Stancl/tenancy 3.4

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions