Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No Policy or Gate for authorizing who can create/revoke tokens? #58

Open
bluec opened this issue Mar 7, 2022 · 4 comments
Open

No Policy or Gate for authorizing who can create/revoke tokens? #58

bluec opened this issue Mar 7, 2022 · 4 comments
Labels
help wanted Extra attention is needed needs more info There was not enough information provided to troubleshoot this further

Comments

@bluec
Copy link

bluec commented Mar 7, 2022

Hi this seems a cool little package and could be just what I need, but I am concerned that there seems to be no authorisation in place to control who can create (or indeed revoke) a token.

It looks like with a bit of messing around with the HTTP request in Nova any user could create or revoke a token for any other user.

Have I got this wrong?

@JeffBeltran
Copy link
Owner

It's was my understanding that Nova will respect auth policies (https://nova.laravel.com/docs/3.0/resources/authorization.html) but I have not tested this. If i get some time i can check on this but a quick way to do this yourself would be to create a policy for the tokens and see if you are able to control it via that.

@JeffBeltran JeffBeltran added help wanted Extra attention is needed needs more info There was not enough information provided to troubleshoot this further labels Mar 7, 2022
@bluec
Copy link
Author

bluec commented Mar 7, 2022

Hi thanks for the response

I think (but am not sure at all!) that Nova will only respect auth Policies for Nova Resources linked to a Model. For Resource Tools the Nova documentation is quite lacking about what authorization is available or built-in. It appears we can chain the canSee method on the tool registration (https://nova.laravel.com/docs/3.0/customization/resource-tools.html#authorization) but its not clear whether this actually authorizes the tool or just prevents it from displaying. I suspect the latter.

From what I can see in the code I fear that any user can just create/view/revoke the token of any other user. My gut feeling is that Policies don't work here and that the included Controller should authorize the request against a Gate.

I will try to do some more testing to see how it all works.

@JeffBeltran
Copy link
Owner

Routing Authorization

When building routes for your tool, you should always add authorization to these routes using Laravel gates or policies.

I would suspect you are right (based on the docs) and we would need to get this sorted... i definitely don't have the time to fix this asap, so im happy to accept a PR that does. Let me know what you find in your testing. Maybe it's a quick fix.

@bluec
Copy link
Author

bluec commented Feb 27, 2024

Two years later I have stumbled upon this package again and again realised that all user API keys are accessible and revokable by anyone, even by somebody not logged in. A popular package with 230,000+ downloads unknowingly exposing user API keys to the world!

Below is an updated controller that checks the Policy of whatever Tokenable model you are using (typically the User model) to ensure that the current user is authorized to view or update that model.

Obviously this requires the appropriate authorization logic in the Policy. If necessary this could be made more granular with viewTokens, createTokens, and revokeTokens methods on the Policy.

It would be good to see an update to this package to add some authorization like this, or at least a big warning on the README that the routes are not protected!

<?php

namespace Jeffbeltran\SanctumTokens\Http;

use Illuminate\Http\Request;
use Laravel\Nova\Nova;

class SanctumController
{
    public function tokens(Request $request, $resourceName, $id)
    {
        $model = Nova::modelInstanceForKey($resourceName)
            ->with("tokens")
            ->find($id);

        if (!$request->user() || $request->user()->cannot('view', $model)) {
            abort(403);
        }

        return $model;
    }

    public function createToken(Request $request, $resourceName, $id)
    {
        $model = Nova::modelInstanceForKey($resourceName)->find($id);

        if (!$request->user() || $request->user()->cannot('update', $model)) {
            abort(403);
        }

        $abilities = collect(explode(",", $request->abilities))
            ->map(function ($item) {
                return trim($item);
            })
            ->toArray();

        $token = $model->createToken($request->name, $abilities);

        return $token->plainTextToken;
    }

    public function revoke(Request $request, $resourceName, $id)
    {
        $model = Nova::modelInstanceForKey($resourceName)
            ->with("tokens")
            ->find($id);

        if (!$request->user() || $request->user()->cannot('update', $model)) {
            abort(403);
        }

        return $model
            ->tokens()
            ->whereKey($request->token_id)
            ->delete();
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed needs more info There was not enough information provided to troubleshoot this further
Projects
None yet
Development

No branches or pull requests

2 participants