Skip to content

Commit

Permalink
Flag parameters as sensitive
Browse files Browse the repository at this point in the history
… if they could contain the database password.
  • Loading branch information
derrabus committed Jan 24, 2023
1 parent 824b327 commit e1aa994
Show file tree
Hide file tree
Showing 27 changed files with 222 additions and 154 deletions.
1 change: 1 addition & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ parameters:
message: '~^Casting to bool something that''s already bool\.$~'
paths:
- src/Connections/PrimaryReadReplicaConnection.php
- src/Driver/SQLite3/Driver.php

# Type check for legacy implementations of the Connection interface
# TODO: remove in 4.0.0
Expand Down
4 changes: 1 addition & 3 deletions src/Cache/QueryCacheProfile.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,7 @@ public function getCacheKey()
*/
public function generateCacheKeys($sql, $params, $types, array $connectionParams = [])
{
if (isset($connectionParams['password'])) {
unset($connectionParams['password']);
}
unset($connectionParams['password']);

$realCacheKey = 'query=' . $sql .
'&params=' . serialize($params) .
Expand Down
4 changes: 3 additions & 1 deletion src/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use Doctrine\DBAL\Types\Type;
use Doctrine\Deprecations\Deprecation;
use LogicException;
use SensitiveParameter;
use Throwable;
use Traversable;

Expand Down Expand Up @@ -173,6 +174,7 @@ class Connection
* @throws Exception
*/
public function __construct(
#[SensitiveParameter]
array $params,
Driver $driver,
?Configuration $config = null,
Expand Down Expand Up @@ -1099,7 +1101,7 @@ public function executeCacheQuery($sql, $params, $types, QueryCacheProfile $qcp)
}

$connectionParams = $this->params;
unset($connectionParams['platform']);
unset($connectionParams['platform'], $connectionParams['password'], $connectionParams['url']);

[$cacheKey, $realKey] = $qcp->generateCacheKeys($sql, $params, $types, $connectionParams);

Expand Down
8 changes: 6 additions & 2 deletions src/Connections/PrimaryReadReplicaConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Doctrine\DBAL\Statement;
use Doctrine\Deprecations\Deprecation;
use InvalidArgumentException;
use SensitiveParameter;

use function array_rand;
use function count;
Expand Down Expand Up @@ -263,8 +264,11 @@ protected function connectTo($connectionName)
*
* @return mixed
*/
protected function chooseConnectionConfiguration($connectionName, $params)
{
protected function chooseConnectionConfiguration(
$connectionName,
#[SensitiveParameter]
$params
) {
if ($connectionName === 'primary') {
return $params['primary'];
}
Expand Down
11 changes: 9 additions & 2 deletions src/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,30 @@
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use SensitiveParameter;

/**
* Driver interface.
* Interface that all DBAL drivers must implement.
*
* @psalm-import-type Params from DriverManager
*/
interface Driver
{
/**
* Attempts to create a connection with the database.
*
* @param mixed[] $params All connection parameters.
* @param array<string, mixed> $params All connection parameters.
* @psalm-param Params $params All connection parameters.
*
* @return DriverConnection The database connection.
*
* @throws Exception
*/
public function connect(array $params);
public function connect(
#[SensitiveParameter]
array $params
);

/**
* Gets the DatabasePlatform instance that provides all the metadata about
Expand Down
2 changes: 1 addition & 1 deletion src/Driver/AbstractOracleDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public function getExceptionConverter(): ExceptionConverter
/**
* Returns an appropriate Easy Connect String for the given parameters.
*
* @param mixed[] $params The connection parameters to return the Easy Connect String for.
* @param array<string, mixed> $params The connection parameters to return the Easy Connect String for.
*
* @return string
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\Middleware;
use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware;
use SensitiveParameter;

class EnableForeignKeys implements Middleware
{
Expand All @@ -15,8 +16,10 @@ public function wrap(Driver $driver): Driver
/**
* {@inheritDoc}
*/
public function connect(array $params): Connection
{
public function connect(
#[SensitiveParameter]
array $params
): Connection {
$connection = parent::connect($params);

$connection->exec('PRAGMA foreign_keys=ON');
Expand Down
20 changes: 14 additions & 6 deletions src/Driver/IBMDB2/DataSourceName.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Doctrine\DBAL\Driver\IBMDB2;

use SensitiveParameter;

use function implode;
use function sprintf;
use function strpos;
Expand All @@ -15,8 +17,10 @@ final class DataSourceName
{
private string $string;

private function __construct(string $string)
{
private function __construct(
#[SensitiveParameter]
string $string
) {
$this->string = $string;
}

Expand All @@ -30,8 +34,10 @@ public function toString(): string
*
* @param array<string,mixed> $params
*/
public static function fromArray(array $params): self
{
public static function fromArray(
#[SensitiveParameter]
array $params
): self {
$chunks = [];

foreach ($params as $key => $value) {
Expand All @@ -46,8 +52,10 @@ public static function fromArray(array $params): self
*
* @param array<string,mixed> $params
*/
public static function fromConnectionParameters(array $params): self
{
public static function fromConnectionParameters(
#[SensitiveParameter]
array $params
): self {
if (isset($params['dbname']) && strpos($params['dbname'], '=') !== false) {
return new self($params['dbname']);
}
Expand Down
7 changes: 5 additions & 2 deletions src/Driver/IBMDB2/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Doctrine\DBAL\Driver\AbstractDB2Driver;
use Doctrine\DBAL\Driver\IBMDB2\Exception\ConnectionFailed;
use SensitiveParameter;

use function db2_connect;
use function db2_pconnect;
Expand All @@ -15,8 +16,10 @@ final class Driver extends AbstractDB2Driver
*
* @return Connection
*/
public function connect(array $params)
{
public function connect(
#[SensitiveParameter]
array $params
) {
$dataSourceName = DataSourceName::fromConnectionParameters($params)->toString();

$username = $params['user'] ?? '';
Expand Down
7 changes: 5 additions & 2 deletions src/Driver/Middleware/AbstractDriverMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\VersionAwarePlatformDriver;
use Doctrine\Deprecations\Deprecation;
use SensitiveParameter;

abstract class AbstractDriverMiddleware implements VersionAwarePlatformDriver
{
Expand All @@ -21,8 +22,10 @@ public function __construct(Driver $wrappedDriver)
/**
* {@inheritdoc}
*/
public function connect(array $params)
{
public function connect(
#[SensitiveParameter]
array $params
) {
return $this->wrappedDriver->connect($params);
}

Expand Down
105 changes: 41 additions & 64 deletions src/Driver/Mysqli/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
use Doctrine\DBAL\Driver\Mysqli\Initializer\Charset;
use Doctrine\DBAL\Driver\Mysqli\Initializer\Options;
use Doctrine\DBAL\Driver\Mysqli\Initializer\Secure;
use Generator;
use mysqli;
use mysqli_sql_exception;

use function count;
use SensitiveParameter;

final class Driver extends AbstractMySQLDriver
{
Expand All @@ -20,8 +20,10 @@ final class Driver extends AbstractMySQLDriver
*
* @return Connection
*/
public function connect(array $params)
{
public function connect(
#[SensitiveParameter]
array $params
) {
if (! empty($params['persistent'])) {
if (! isset($params['host'])) {
throw HostRequired::forPersistentConnection();
Expand All @@ -32,27 +34,9 @@ public function connect(array $params)
$host = $params['host'] ?? null;
}

$flags = 0;

$preInitializers = $postInitializers = [];

if (isset($params['driverOptions'])) {
$driverOptions = $params['driverOptions'];

if (isset($driverOptions[Connection::OPTION_FLAGS])) {
$flags = $driverOptions[Connection::OPTION_FLAGS];
unset($driverOptions[Connection::OPTION_FLAGS]);
}

$preInitializers = $this->withOptions($preInitializers, $driverOptions);
}

$preInitializers = $this->withSecure($preInitializers, $params);
$postInitializers = $this->withCharset($postInitializers, $params);

$connection = new mysqli();

foreach ($preInitializers as $initializer) {
foreach ($this->compilePreInitializers($params) as $initializer) {
$initializer->initialize($connection);
}

Expand All @@ -64,7 +48,7 @@ public function connect(array $params)
$params['dbname'] ?? null,
$params['port'] ?? null,
$params['unix_socket'] ?? null,
$flags,
$params['driverOptions'][Connection::OPTION_FLAGS] ?? 0,
);
} catch (mysqli_sql_exception $e) {
throw ConnectionFailed::upcast($e);
Expand All @@ -74,67 +58,60 @@ public function connect(array $params)
throw ConnectionFailed::new($connection);
}

foreach ($postInitializers as $initializer) {
foreach ($this->compilePostInitializers($params) as $initializer) {
$initializer->initialize($connection);
}

return new Connection($connection);
}

/**
* @param list<Initializer> $initializers
* @param array<int,mixed> $options
* @param array<string, mixed> $params
*
* @return list<Initializer>
* @return Generator<int, Initializer>
*/
private function withOptions(array $initializers, array $options): array
{
if (count($options) !== 0) {
$initializers[] = new Options($options);
private function compilePreInitializers(
#[SensitiveParameter]
array $params
): Generator {
unset($params['driverOptions'][Connection::OPTION_FLAGS]);

if (isset($params['driverOptions']) && $params['driverOptions'] !== []) {
yield new Options($params['driverOptions']);
}

return $initializers;
}

/**
* @param list<Initializer> $initializers
* @param array<string,mixed> $params
*
* @return list<Initializer>
*/
private function withSecure(array $initializers, array $params): array
{
if (
isset($params['ssl_key']) ||
isset($params['ssl_cert']) ||
isset($params['ssl_ca']) ||
isset($params['ssl_capath']) ||
isset($params['ssl_cipher'])
! isset($params['ssl_key']) &&
! isset($params['ssl_cert']) &&
! isset($params['ssl_ca']) &&
! isset($params['ssl_capath']) &&
! isset($params['ssl_cipher'])
) {
$initializers[] = new Secure(
$params['ssl_key'] ?? '',
$params['ssl_cert'] ?? '',
$params['ssl_ca'] ?? '',
$params['ssl_capath'] ?? '',
$params['ssl_cipher'] ?? '',
);
return;
}

return $initializers;
yield new Secure(
$params['ssl_key'] ?? '',
$params['ssl_cert'] ?? '',
$params['ssl_ca'] ?? '',
$params['ssl_capath'] ?? '',
$params['ssl_cipher'] ?? '',
);
}

/**
* @param list<Initializer> $initializers
* @param array<string,mixed> $params
* @param array<string, mixed> $params
*
* @return list<Initializer>
* @return Generator<int, Initializer>
*/
private function withCharset(array $initializers, array $params): array
{
if (isset($params['charset'])) {
$initializers[] = new Charset($params['charset']);
private function compilePostInitializers(
#[SensitiveParameter]
array $params
): Generator {
if (! isset($params['charset'])) {
return;
}

return $initializers;
yield new Charset($params['charset']);
}
}
Loading

0 comments on commit e1aa994

Please sign in to comment.