Merge pull request #7244 from nupplaphil/task/hidden_string

Introduce HiddenString for Config-Values
This commit is contained in:
Hypolite Petovan 2019-06-10 10:50:41 -04:00 committed by GitHub
commit 151c026a8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 161 additions and 24 deletions

View file

@ -37,6 +37,7 @@
"mobiledetect/mobiledetectlib": "2.8.*", "mobiledetect/mobiledetectlib": "2.8.*",
"monolog/monolog": "^1.24", "monolog/monolog": "^1.24",
"nikic/fast-route": "^1.3", "nikic/fast-route": "^1.3",
"paragonie/hidden-string": "^1.0",
"pear/text_languagedetect": "1.*", "pear/text_languagedetect": "1.*",
"pragmarx/google2fa": "^5.0", "pragmarx/google2fa": "^5.0",
"pragmarx/recovery": "^0.1.0", "pragmarx/recovery": "^0.1.0",

84
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "67821d2270bdf8cdd24e7a047b9544e7", "content-hash": "eb985236d64ed0b0fe1fc2e4ac6616e2",
"packages": [ "packages": [
{ {
"name": "asika/simple-console", "name": "asika/simple-console",
@ -1723,25 +1723,24 @@
}, },
{ {
"name": "paragonie/constant_time_encoding", "name": "paragonie/constant_time_encoding",
"version": "v1.0.4", "version": "v2.2.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/paragonie/constant_time_encoding.git", "url": "https://github.com/paragonie/constant_time_encoding.git",
"reference": "2132f0f293d856026d7d11bd81b9f4a23a1dc1f6" "reference": "55af0dc01992b4d0da7f6372e2eac097bbbaffdb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/2132f0f293d856026d7d11bd81b9f4a23a1dc1f6", "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/55af0dc01992b4d0da7f6372e2eac097bbbaffdb",
"reference": "2132f0f293d856026d7d11bd81b9f4a23a1dc1f6", "reference": "55af0dc01992b4d0da7f6372e2eac097bbbaffdb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^5.3|^7" "php": "^7"
}, },
"require-dev": { "require-dev": {
"paragonie/random_compat": "^1.4|^2", "phpunit/phpunit": "^6|^7",
"phpunit/phpunit": "4.*|5.*", "vimeo/psalm": "^1|^2"
"vimeo/psalm": "^0.3|^1"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -1782,7 +1781,56 @@
"hex2bin", "hex2bin",
"rfc4648" "rfc4648"
], ],
"time": "2018-04-30T17:57:16+00:00" "time": "2019-01-03T20:26:31+00:00"
},
{
"name": "paragonie/hidden-string",
"version": "v1.0.0",
"source": {
"type": "git",
"url": "https://github.com/paragonie/hidden-string.git",
"reference": "0bbb00be0e33b8e1d48fa79ea35cd42d3091a936"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/hidden-string/zipball/0bbb00be0e33b8e1d48fa79ea35cd42d3091a936",
"reference": "0bbb00be0e33b8e1d48fa79ea35cd42d3091a936",
"shasum": ""
},
"require": {
"paragonie/constant_time_encoding": "^2",
"paragonie/sodium_compat": "^1.6",
"php": "^7"
},
"require-dev": {
"phpunit/phpunit": "^6|^7",
"vimeo/psalm": "^1"
},
"type": "library",
"autoload": {
"psr-4": {
"ParagonIE\\HiddenString\\": "./src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MPL-2.0"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "info@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "Encapsulate strings in an object to hide them from stack traces",
"homepage": "https://github.com/paragonie/hidden-string",
"keywords": [
"hidden",
"stack trace",
"string"
],
"time": "2018-05-07T20:28:06+00:00"
}, },
{ {
"name": "paragonie/random_compat", "name": "paragonie/random_compat",
@ -2793,12 +2841,12 @@
"version": "v1.6.5", "version": "v1.6.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/mikey179/vfsStream.git", "url": "https://github.com/bovigo/vfsStream.git",
"reference": "d5fec95f541d4d71c4823bb5e30cf9b9e5b96145" "reference": "d5fec95f541d4d71c4823bb5e30cf9b9e5b96145"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/mikey179/vfsStream/zipball/d5fec95f541d4d71c4823bb5e30cf9b9e5b96145", "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/d5fec95f541d4d71c4823bb5e30cf9b9e5b96145",
"reference": "d5fec95f541d4d71c4823bb5e30cf9b9e5b96145", "reference": "d5fec95f541d4d71c4823bb5e30cf9b9e5b96145",
"shasum": "" "shasum": ""
}, },
@ -3701,7 +3749,7 @@
} }
], ],
"description": "Provides the functionality to compare PHP values for equality", "description": "Provides the functionality to compare PHP values for equality",
"homepage": "http://www.github.com/sebastianbergmann/comparator", "homepage": "https://github.com/sebastianbergmann/comparator",
"keywords": [ "keywords": [
"comparator", "comparator",
"compare", "compare",
@ -3803,7 +3851,7 @@
} }
], ],
"description": "Provides functionality to handle HHVM/PHP environments", "description": "Provides functionality to handle HHVM/PHP environments",
"homepage": "http://www.github.com/sebastianbergmann/environment", "homepage": "https://github.com/sebastianbergmann/environment",
"keywords": [ "keywords": [
"Xdebug", "Xdebug",
"environment", "environment",
@ -3871,7 +3919,7 @@
} }
], ],
"description": "Provides the functionality to export PHP variables for visualization", "description": "Provides the functionality to export PHP variables for visualization",
"homepage": "http://www.github.com/sebastianbergmann/exporter", "homepage": "https://github.com/sebastianbergmann/exporter",
"keywords": [ "keywords": [
"export", "export",
"exporter" "exporter"
@ -3923,7 +3971,7 @@
} }
], ],
"description": "Snapshotting of global state", "description": "Snapshotting of global state",
"homepage": "http://www.github.com/sebastianbergmann/global-state", "homepage": "https://github.com/sebastianbergmann/global-state",
"keywords": [ "keywords": [
"global state" "global state"
], ],
@ -4025,7 +4073,7 @@
} }
], ],
"description": "Provides functionality to recursively process PHP variables", "description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context", "homepage": "https://github.com/sebastianbergmann/recursion-context",
"time": "2016-11-19T07:33:16+00:00" "time": "2016-11-19T07:33:16+00:00"
}, },
{ {
@ -4158,7 +4206,7 @@
}, },
{ {
"name": "Gert de Pagter", "name": "Gert de Pagter",
"email": "backendtea@gmail.com" "email": "BackEndTea@gmail.com"
} }
], ],
"description": "Symfony polyfill for ctype functions", "description": "Symfony polyfill for ctype functions",

View file

@ -2,6 +2,8 @@
namespace Friendica\Core\Config\Cache; namespace Friendica\Core\Config\Cache;
use ParagonIE\HiddenString\HiddenString;
/** /**
* The Friendica config cache for the application * The Friendica config cache for the application
* Initial, all *.config.php files are loaded into this cache with the * Initial, all *.config.php files are loaded into this cache with the
@ -15,10 +17,17 @@ class ConfigCache implements IConfigCache, IPConfigCache
private $config; private $config;
/** /**
* @param array $config A initial config array * @var bool
*/ */
public function __construct(array $config = []) private $hidePasswordOutput;
/**
* @param array $config A initial config array
* @param bool $hidePasswordOutput True, if cache variables should take extra care of password values
*/
public function __construct(array $config = [], $hidePasswordOutput = true)
{ {
$this->hidePasswordOutput = $hidePasswordOutput;
$this->load($config); $this->load($config);
} }
@ -84,8 +93,13 @@ class ConfigCache implements IConfigCache, IPConfigCache
$this->config[$cat] = []; $this->config[$cat] = [];
} }
$this->config[$cat][$key] = $value; if ($this->hidePasswordOutput &&
$key == 'password' &&
!empty($value) && is_string($value)) {
$this->config[$cat][$key] = new HiddenString((string) $value);
} else {
$this->config[$cat][$key] = $value;
}
return true; return true;
} }

View file

@ -88,7 +88,7 @@ class Configuration
if (isset($dbvalue)) { if (isset($dbvalue)) {
$this->configCache->set($cat, $key, $dbvalue); $this->configCache->set($cat, $key, $dbvalue);
return $dbvalue; unset($dbvalue);
} }
} }

View file

@ -6,6 +6,7 @@ use Friendica\Core\Config\Cache;
use Friendica\Database; use Friendica\Database;
use Friendica\Util\Logger\VoidLogger; use Friendica\Util\Logger\VoidLogger;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
use ParagonIE\HiddenString\HiddenString;
class DBFactory class DBFactory
{ {
@ -45,7 +46,7 @@ class DBFactory
} else { } else {
$db_user = $server['MYSQL_USER']; $db_user = $server['MYSQL_USER'];
} }
$db_pass = (string) $server['MYSQL_PASSWORD']; $db_pass = new HiddenString((string) $server['MYSQL_PASSWORD']);
$db_data = $server['MYSQL_DATABASE']; $db_data = $server['MYSQL_DATABASE'];
} }

View file

@ -275,4 +275,77 @@ class ConfigCacheTest extends MockedTest
$this->assertEmpty($configCache->keyDiff($diffConfig)); $this->assertEmpty($configCache->keyDiff($diffConfig));
} }
/**
* Test the default hiding of passwords inside the cache
*/
public function testPasswordHide()
{
$configCache = new ConfigCache([
'database' => [
'password' => 'supersecure',
'username' => 'notsecured',
],
]);
$this->assertEquals('supersecure', $configCache->get('database', 'password'));
$this->assertNotEquals('supersecure', print_r($configCache->get('database', 'password'), true));
$this->assertEquals('notsecured', print_r($configCache->get('database', 'username'), true));
}
/**
* Test disabling the hiding of passwords inside the cache
*/
public function testPasswordShow()
{
$configCache = new ConfigCache([
'database' => [
'password' => 'supersecure',
'username' => 'notsecured',
],
], false);
$this->assertEquals('supersecure', $configCache->get('database', 'password'));
$this->assertEquals('supersecure', print_r($configCache->get('database', 'password'), true));
$this->assertEquals('notsecured', print_r($configCache->get('database', 'username'), true));
}
/**
* Test a empty password
*/
public function testEmptyPassword()
{
$configCache = new ConfigCache([
'database' => [
'password' => '',
'username' => '',
]
]);
$this->assertEmpty($configCache->get('database', 'password'));
$this->assertEmpty($configCache->get('database', 'username'));
}
public function testWrongTypePassword()
{
$configCache = new ConfigCache([
'database' => [
'password' => new \stdClass(),
'username' => '',
]
]);
$this->assertNotEmpty($configCache->get('database', 'password'));
$this->assertEmpty($configCache->get('database', 'username'));
$configCache = new ConfigCache([
'database' => [
'password' => 23,
'username' => '',
]
]);
$this->assertEquals(23, $configCache->get('database', 'password'));
$this->assertEmpty($configCache->get('database', 'username'));
}
} }