GenerateKeyPairCommand::getKeyPair()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 16
ccs 0
cts 8
cp 0
rs 9.4285
c 1
b 0
f 0
cc 1
eloc 10
nc 1
nop 1
crap 2
1
<?php
2
3
namespace Mvdstam\Oauth2ServerLaravel\Commands;
4
5
use Exception;
6
use Illuminate\Console\Command;
7
8
class GenerateKeyPairCommand extends Command
9
{
10
11
    /**
12
     * @var string
13
     */
14
    protected $signature = 'oauth2-server:generate-key-pair {passphrase?}';
15
16
    /**
17
     * @var string
18
     */
19
    protected $description = 'Generate a RSA keypair for use in your OAuth2 server';
20
21
    public function handle()
22
    {
23
        if (!($passphrase = $this->argument('passphrase'))) {
24
            $passphrase = $this->secret('Enter passphrase or leave empty (not recommended)');
25
        }
26
27
        $this->info('Creating storage directory...');
28
        $storagePath = storage_path('app/oauth2-server');
29
        if (!is_dir($storagePath) && !mkdir($storagePath, 0777, true)) {
0 ignored issues
show
Security File Manipulation introduced by
$storagePath can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_SERVER
    in vendor/src/Illuminate/Foundation/Bootstrap/SetRequestForConsole.php on line 20
  2. Data is passed through array_replace()
    in vendor/Request.php on line 324
  3. Data is passed through call_user_func()
    in vendor/Request.php on line 1936
  4. \Illuminate\Http\Request::create($url, 'GET', array(), array(), array(), $_SERVER) is passed to Container::instance()
    in vendor/src/Illuminate/Foundation/Bootstrap/SetRequestForConsole.php on line 20
  5. Container::$instances is assigned
    in vendor/src/Illuminate/Container/Container.php on line 346
  6. Tainted property Container::$instances is read
    in vendor/src/Illuminate/Container/Container.php on line 635
  7. Container::make() returns tainted data
    in vendor/src/Illuminate/Foundation/helpers.php on line 106
  8. app() returns tainted data
    in vendor/src/Illuminate/Foundation/helpers.php on line 759
  9. storage_path() returns tainted data, and $storagePath is assigned
    in src/Commands/GenerateKeyPairCommand.php on line 28

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
30
            throw new Exception('Unable to create storage directory for oauth2 server');
31
        }
32
33
        $this->info('Generating keypair...');
34
        list($publicKey, $privateKey) = $this->getKeyPair($passphrase);
0 ignored issues
show
Bug introduced by
It seems like $passphrase can also be of type array; however, Mvdstam\Oauth2ServerLara...irCommand::getKeyPair() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
35
36
        $publicKeyFile = $storagePath . DIRECTORY_SEPARATOR . 'public.pem';
37
        $privateKeyFile = $storagePath . DIRECTORY_SEPARATOR . 'private.pem';
38
39
        if (is_file($publicKeyFile) || is_file($privateKeyFile)) {
40
            throw new Exception('Unable to store keys files because they already exist on disk.');
41
        }
42
43
        $this->info('Storing keys...');
44
        if (!file_put_contents($publicKeyFile, $publicKey) || !file_put_contents($privateKeyFile, $privateKey)) {
0 ignored issues
show
Security File Manipulation introduced by
$publicKeyFile can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_SERVER
    in vendor/src/Illuminate/Foundation/Bootstrap/SetRequestForConsole.php on line 20
  2. Data is passed through array_replace()
    in vendor/Request.php on line 324
  3. Data is passed through call_user_func()
    in vendor/Request.php on line 1936
  4. \Illuminate\Http\Request::create($url, 'GET', array(), array(), array(), $_SERVER) is passed to Container::instance()
    in vendor/src/Illuminate/Foundation/Bootstrap/SetRequestForConsole.php on line 20
  5. Container::$instances is assigned
    in vendor/src/Illuminate/Container/Container.php on line 346
  6. Tainted property Container::$instances is read
    in vendor/src/Illuminate/Container/Container.php on line 635
  7. Container::make() returns tainted data
    in vendor/src/Illuminate/Foundation/helpers.php on line 106
  8. app() returns tainted data
    in vendor/src/Illuminate/Foundation/helpers.php on line 759
  9. storage_path() returns tainted data, and $storagePath is assigned
    in src/Commands/GenerateKeyPairCommand.php on line 28
  10. $publicKeyFile is assigned
    in src/Commands/GenerateKeyPairCommand.php on line 36

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
Security File Manipulation introduced by
$privateKeyFile can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_SERVER
    in vendor/src/Illuminate/Foundation/Bootstrap/SetRequestForConsole.php on line 20
  2. Data is passed through array_replace()
    in vendor/Request.php on line 324
  3. Data is passed through call_user_func()
    in vendor/Request.php on line 1936
  4. \Illuminate\Http\Request::create($url, 'GET', array(), array(), array(), $_SERVER) is passed to Container::instance()
    in vendor/src/Illuminate/Foundation/Bootstrap/SetRequestForConsole.php on line 20
  5. Container::$instances is assigned
    in vendor/src/Illuminate/Container/Container.php on line 346
  6. Tainted property Container::$instances is read
    in vendor/src/Illuminate/Container/Container.php on line 635
  7. Container::make() returns tainted data
    in vendor/src/Illuminate/Foundation/helpers.php on line 106
  8. app() returns tainted data
    in vendor/src/Illuminate/Foundation/helpers.php on line 759
  9. storage_path() returns tainted data, and $storagePath is assigned
    in src/Commands/GenerateKeyPairCommand.php on line 28
  10. $privateKeyFile is assigned
    in src/Commands/GenerateKeyPairCommand.php on line 37

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
45
            throw new Exception('Unable to write keys to file. Is the directory writable?');
46
        }
47
48
        $this->info('Keys generated succesfully!');
49
    }
50
51
    /**
52
     * @param string|null $passphrase
53
     * @return string[]
54
     */
55
    protected function getKeyPair($passphrase = null)
56
    {
57
        $config = [
58
            'digest_alg' => 'sha256',
59
            'private_key_bits' => 4096,
60
            'private_key_type' => OPENSSL_KEYTYPE_RSA,
61
        ];
62
63
        $keyPair = openssl_pkey_new($config);
64
        openssl_pkey_export($keyPair, $privateKey, $passphrase);
65
66
        return [
67
            openssl_pkey_get_details($keyPair)['key'],
68
            $privateKey
69
        ];
70
    }
71
}
72