Issues (71)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/Providers/OAuthServiceProvider.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Rinvex\Oauth\Providers;
6
7
use DateInterval;
8
use Illuminate\Support\Str;
9
use Rinvex\Oauth\Models\Client;
10
use Illuminate\Auth\AuthManager;
11
use Illuminate\Auth\RequestGuard;
12
use Rinvex\Oauth\Models\AuthCode;
13
use Illuminate\Auth\Events\Logout;
14
use League\OAuth2\Server\CryptKey;
15
use Rinvex\Oauth\Guards\TokenGuard;
16
use Rinvex\Oauth\OAuthUserProvider;
17
use Illuminate\Support\Facades\Auth;
18
use Rinvex\Oauth\Models\AccessToken;
19
use Illuminate\Support\Facades\Event;
20
use Rinvex\Oauth\Models\RefreshToken;
21
use Illuminate\Support\Facades\Cookie;
22
use Rinvex\Oauth\Grants\AuthCodeGrant;
23
use Rinvex\Oauth\Grants\PasswordGrant;
24
use Illuminate\Support\Facades\Request;
25
use Illuminate\Support\ServiceProvider;
26
use Rinvex\Support\Traits\ConsoleTools;
27
use League\OAuth2\Server\ResourceServer;
28
use Rinvex\Oauth\Grants\RefreshTokenGrant;
29
use Rinvex\Oauth\Grants\PersonalAccessGrant;
30
use League\OAuth2\Server\AuthorizationServer;
31
use League\OAuth2\Server\Grant\ImplicitGrant;
32
use Rinvex\Oauth\Repositories\UserRepository;
33
use Rinvex\Oauth\Console\Commands\KeysCommand;
34
use Rinvex\Oauth\Repositories\ScopeRepository;
35
use Rinvex\Oauth\Console\Commands\PurgeCommand;
36
use Rinvex\Oauth\Grants\ClientCredentialsGrant;
37
use Rinvex\Oauth\Repositories\ClientRepository;
38
use Rinvex\Oauth\Console\Commands\ClientCommand;
39
use Rinvex\Oauth\Console\Commands\MigrateCommand;
40
use Rinvex\Oauth\Console\Commands\PublishCommand;
41
use Rinvex\Oauth\Repositories\AuthCodeRepository;
42
use Rinvex\Oauth\Console\Commands\RollbackCommand;
43
use Rinvex\Oauth\Repositories\AccessTokenRepository;
44
use Rinvex\Oauth\Repositories\RefreshTokenRepository;
45
46
class OAuthServiceProvider extends ServiceProvider
47
{
48
    use ConsoleTools;
49
50
    /**
51
     * Bootstrap the application services.
52
     *
53
     * @return void
54
     */
55
    public function boot()
56
    {
57
        // Publish Resources
58
        $this->publishesConfig('rinvex/laravel-oauth');
59
        $this->publishesMigrations('rinvex/laravel-oauth');
60
        ! $this->autoloadMigrations('rinvex/laravel-oauth') || $this->loadMigrationsFrom(__DIR__.'/../../database/migrations');
61
62
        $this->deleteCookieOnLogout();
63
64
        if ($this->app->runningInConsole()) {
65
            $this->commands([
66
                KeysCommand::class,
67
                PurgeCommand::class,
68
                ClientCommand::class,
69
                MigrateCommand::class,
70
                PublishCommand::class,
71
                RollbackCommand::class,
72
            ]);
73
        }
74
    }
75
76
    /**
77
     * Register the service provider.
78
     *
79
     * @return void
80
     */
81
    public function register()
82
    {
83
        // Merge config
84
        $this->mergeConfigFrom(realpath(__DIR__.'/../../config/config.php'), 'rinvex.oauth');
85
86
        // Bind eloquent models to IoC container
87
        $this->registerModels([
88
            'rinvex.oauth.client' => Client::class,
89
            'rinvex.oauth.auth_code' => AuthCode::class,
90
            'rinvex.oauth.access_token' => AccessToken::class,
91
            'rinvex.oauth.refresh_token' => RefreshToken::class,
92
        ]);
93
94
        $this->registerAuthorizationServer();
95
        $this->registerClientRepository();
96
        $this->registerResourceServer();
97
        $this->registerGuard();
98
    }
99
100
    /**
101
     * Register the authorization server.
102
     *
103
     * @return void
104
     */
105
    protected function registerAuthorizationServer()
106
    {
107
        $this->app->singleton(AuthorizationServer::class, function () {
108
            return tap($this->makeAuthorizationServer(), function ($server) {
109
                ! config('rinvex.oauth.default_scope') || $server->setDefaultScope(config('rinvex.oauth.default_scope'));
110
111
                foreach (collect(config('rinvex.oauth.grants'))->filter(fn ($args) => $args['enabled']) as $grant => $options) {
0 ignored issues
show
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_DOUBLE_ARROW, expecting ',' or ')'
Loading history...
112
                    $makeGrantMethod = "make{$grant}Grant";
113
114
                    $server->enableGrantType(
115
                        $this->{$makeGrantMethod}(),
116
                        $options['expire_in']
117
                    );
118
                }
119
            });
120
        });
121
    }
122
123
    /**
124
     * Create and configure an instance of the personal access grant.
125
     *
126
     * @return \Rinvex\Oauth\Grants\PersonalAccessGrant
127
     */
128
    protected function makePersonalAccessGrant()
129
    {
130
        return new PersonalAccessGrant();
131
    }
132
133
    /**
134
     * Create and configure an instance of the client credentials grant.
135
     *
136
     * @return \League\OAuth2\Server\Grant\ClientCredentialsGrant
137
     */
138
    protected function makeClientCredentialsGrant()
139
    {
140
        return new ClientCredentialsGrant();
141
    }
142
143
    /**
144
     * Create and configure an instance of the Auth Code grant.
145
     *
146
     * @return \League\OAuth2\Server\Grant\AuthCodeGrant
147
     */
148
    protected function makeAuthCodeGrant()
149
    {
150
        return tap($this->buildAuthCodeGrant(), function ($grant) {
151
            $grant->setRefreshTokenTTL(config('rinvex.oauth.grants.AuthCode.expire_in'));
152
        });
153
    }
154
155
    /**
156
     * Create and configure a Refresh Token grant instance.
157
     *
158
     * @return \League\OAuth2\Server\Grant\RefreshTokenGrant
159
     */
160
    protected function makeRefreshTokenGrant()
161
    {
162
        $repository = $this->app->make(RefreshTokenRepository::class);
163
164
        return tap(new RefreshTokenGrant($repository), function ($grant) {
165
            $grant->setRefreshTokenTTL(config('rinvex.oauth.grants.RefreshToken.expire_in'));
166
        });
167
    }
168
169
    /**
170
     * Create and configure a Password grant instance.
171
     *
172
     * @return \League\OAuth2\Server\Grant\PasswordGrant
173
     */
174
    protected function makePasswordGrant()
175
    {
176
        $grant = new PasswordGrant(
177
            $this->app->make(UserRepository::class),
178
            $this->app->make(RefreshTokenRepository::class)
179
        );
180
181
        $grant->setRefreshTokenTTL(config('rinvex.oauth.grants.Password.expire_in'));
182
183
        return $grant;
184
    }
185
186
    /**
187
     * Create and configure an instance of the Implicit grant.
188
     *
189
     * @return \League\OAuth2\Server\Grant\ImplicitGrant
190
     */
191
    protected function makeImplicitGrant()
192
    {
193
        return new ImplicitGrant(config('rinvex.oauth.grants.Implicit.expire_in'));
194
    }
195
196
    /**
197
     * Build the Auth Code grant instance.
198
     *
199
     * @return \League\OAuth2\Server\Grant\AuthCodeGrant
200
     */
201
    protected function buildAuthCodeGrant()
202
    {
203
        return new AuthCodeGrant(
204
            $this->app->make(AuthCodeRepository::class),
205
            $this->app->make(RefreshTokenRepository::class),
206
            new DateInterval('PT10M')
207
        );
208
    }
209
210
    /**
211
     * Make the authorization service instance.
212
     *
213
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
214
     *
215
     * @return \League\OAuth2\Server\AuthorizationServer
216
     */
217
    public function makeAuthorizationServer()
218
    {
219
        return new AuthorizationServer(
220
            $this->app->make(ClientRepository::class),
221
            $this->app->make(AccessTokenRepository::class),
222
            $this->app->make(ScopeRepository::class),
223
            $this->makeCryptKey('private'),
224
            app('encrypter')->getKey()
225
        );
226
    }
227
228
    /**
229
     * Register the client repository.
230
     *
231
     * @return void
232
     */
233
    protected function registerClientRepository()
234
    {
235
        $this->app->singleton(ClientRepository::class, function () {
236
            return new ClientRepository();
237
        });
238
    }
239
240
    /**
241
     * Register the resource server.
242
     *
243
     * @return void
244
     */
245
    protected function registerResourceServer()
246
    {
247
        $this->app->singleton(ResourceServer::class, function () {
248
            return new ResourceServer(
249
                $this->app->make(AccessTokenRepository::class),
250
                $this->makeCryptKey('public')
251
            );
252
        });
253
    }
254
255
    /**
256
     * Create a CryptKey instance without permissions check.
257
     *
258
     * @param string $type
259
     *
260
     * @return \League\OAuth2\Server\CryptKey
261
     */
262
    protected function makeCryptKey($type)
263
    {
264
        $key = str_replace('\\n', "\n", config("rinvex.oauth.{$type}_key"));
265
266
        if (! $key) {
267
            $key = 'file://'.KeysCommand::keyPath('oauth-'.$type.'.key');
268
        }
269
270
        return new CryptKey($key, null, false);
271
    }
272
273
    /**
274
     * Register the token guard.
275
     *
276
     * @return void
277
     */
278
    protected function registerGuard()
279
    {
280
        Auth::resolved(function (AuthManager $auth) {
281
            $auth->extend('oauth', function ($app, $name, array $config) {
282
                return tap($this->makeGuard($config), function ($guard) {
283
                    $this->app->refresh('request', $guard, 'setRequest');
284
                });
285
            });
286
        });
287
    }
288
289
    /**
290
     * Make an instance of the token guard.
291
     *
292
     * @param array $config
293
     *
294
     * @return \Illuminate\Auth\RequestGuard
295
     */
296
    protected function makeGuard(array $config)
297
    {
298
        return new RequestGuard(function ($request) use ($config) {
299
            return (new TokenGuard(
300
                $this->app->make(ResourceServer::class),
301
                new OAuthUserProvider(Auth::createUserProvider($config['provider']), Str::singular($config['provider'])),
302
                $this->app->make('encrypter')
303
            ))->user($request);
304
        }, $this->app['request']);
305
    }
306
307
    /**
308
     * Register the cookie deletion event handler.
309
     *
310
     * @return void
311
     */
312
    protected function deleteCookieOnLogout()
313
    {
314
        Event::listen(Logout::class, function () {
315
            if (Request::hasCookie(config('rinvex.oauth.cookie'))) {
316
                Cookie::queue(Cookie::forget(config('rinvex.oauth.cookie')));
317
            }
318
        });
319
    }
320
}
321