From 0979b67e1baf88d7534d39c9744801a54d487b7f Mon Sep 17 00:00:00 2001 From: nashe Date: Mon, 18 Dec 2017 22:59:42 +0100 Subject: Add hash_equals polyfill and related tests --- app/helpers.php | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++- tests/HelpersTest.php | 15 +++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 tests/HelpersTest.php diff --git a/app/helpers.php b/app/helpers.php index 3bce65f..8765fc6 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -1,5 +1,23 @@ assertTrue(_hash_equals('abc', 'abc')); + $this->assertFalse(_hash_equals('abc', 'ab')); + $this->assertFalse(_hash_equals('ab', 'abc')); + $this->assertFalse(_hash_equals('abcd', 'adbc')); + $this->assertFalse(_hash_equals(0, 0)); + } +} -- cgit v1.2.1 From ace3788763e40161b346757a5178bbe2cc6e7773 Mon Sep 17 00:00:00 2001 From: nashe Date: Sat, 23 Dec 2017 21:07:30 +0100 Subject: Give a session to the users --- admin/login.php | 5 ++++- admin/logout.php | 9 +++++++-- app/app.php | 2 ++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/admin/login.php b/admin/login.php index 3ba4d2b..a95e59f 100755 --- a/admin/login.php +++ b/admin/login.php @@ -1,10 +1,13 @@
diff --git a/admin/logout.php b/admin/logout.php index 6dd32aa..adb843f 100644 --- a/admin/logout.php +++ b/admin/logout.php @@ -1,5 +1,10 @@ \ No newline at end of file +die(); diff --git a/app/app.php b/app/app.php index a6232cf..64c120a 100755 --- a/app/app.php +++ b/app/app.php @@ -7,6 +7,8 @@ require_once __DIR__.'/../vendor/autoload.php'; $savedConfig = __DIR__.'/../custom/config.yml'; $moon_version = file_get_contents(__DIR__.'/../VERSION'); +session_start(); + if (is_installed()) { $conf = Spyc::YAMLLoad($savedConfig); -- cgit v1.2.1 From 20952e3f133bb2097f9f86fd2f2fffe4870d4228 Mon Sep 17 00:00:00 2001 From: nashe Date: Sat, 23 Dec 2017 21:08:23 +0100 Subject: Implement and expose a CSRF mitigation --- app/app.php | 2 +- app/classes/CSRF.php | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 app/classes/CSRF.php diff --git a/app/app.php b/app/app.php index 64c120a..0797cc7 100755 --- a/app/app.php +++ b/app/app.php @@ -29,4 +29,4 @@ if (is_installed()) { } $l10n = new Simplel10n($conf['locale']); - +$csrf = new CSRF(); diff --git a/app/classes/CSRF.php b/app/classes/CSRF.php new file mode 100644 index 0000000..3e23380 --- /dev/null +++ b/app/classes/CSRF.php @@ -0,0 +1,49 @@ + Date: Sat, 23 Dec 2017 21:08:44 +0100 Subject: Add CSRF token checks --- admin/administration.php | 2 ++ admin/changepassword.php | 4 +++- admin/index.php | 2 ++ admin/subscriptions.php | 4 ++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/admin/administration.php b/admin/administration.php index 34afe73..26f6710 100755 --- a/admin/administration.php +++ b/admin/administration.php @@ -24,6 +24,7 @@ $page_content = <<<"FRAGMENT"

{$l10n->getString('Clear cache')}

+

{$l10n->getString('Clearing the cache will make moonmoon reload all feeds.')}

@@ -32,6 +33,7 @@ $page_content = <<<"FRAGMENT"

{$l10n->getString('Change administrator password')}

+

diff --git a/admin/changepassword.php b/admin/changepassword.php index 8c38769..3b4500e 100644 --- a/admin/changepassword.php +++ b/admin/changepassword.php @@ -1,7 +1,9 @@ verify($_POST['_csrf'], 'frmPassword') && isset($_POST['password']) && ('' != $_POST['password'])) { $out = ''; file_put_contents(__DIR__.'/inc/pwd.inc.php', $out); die("Password changed. Login"); diff --git a/admin/index.php b/admin/index.php index a01b77b..0118923 100755 --- a/admin/index.php +++ b/admin/index.php @@ -79,6 +79,7 @@ ob_start();

+ @@ -87,6 +88,7 @@ ob_start();

+

diff --git a/admin/subscriptions.php b/admin/subscriptions.php index f8e4c2c..0606c89 100755 --- a/admin/subscriptions.php +++ b/admin/subscriptions.php @@ -7,6 +7,10 @@ function removeSlashes(&$item, $key){ $item = stripslashes($item); } +if (!$csrf->verify($_POST['_csrf'], 'feedmanage')) { + die('Invalid CSRF token!'); +} + if (isset($_POST['opml']) || isset($_POST['add'])) { // Load config and old OPML -- cgit v1.2.1 From 17665eafb7e271198e6d11d57aae3593664dac58 Mon Sep 17 00:00:00 2001 From: nashe Date: Tue, 2 Jan 2018 19:24:07 +0100 Subject: Add paragonie/random_compat to implement a polyfill for random_bytes --- app/helpers.php | 5 +++++ composer.json | 3 ++- composer.lock | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/app/helpers.php b/app/helpers.php index 8765fc6..01d0086 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -14,6 +14,11 @@ function register_polyfills() call_user_func_array('_hash_equals', func_get_args()); } } + + if (!function_exists('random_bytes')) { + // If this function does not exist, it will be exposed + // automatically by paragonie/random_compat. + } } register_polyfills(); diff --git a/composer.json b/composer.json index c43b48e..ea5032d 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,8 @@ "require": { "php": "^5.6 || ^7.0", "mustangostang/spyc": "0.5.1", - "simplepie/simplepie": "^1.5" + "simplepie/simplepie": "^1.5", + "paragonie/random_compat": "^2.0" }, "require-dev": { "guzzlehttp/guzzle": "^6.3", diff --git a/composer.lock b/composer.lock index 1d3cf2e..7959c9c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "381ab1da48dd363669e218a50e19f0b7", + "content-hash": "a4fc919a4e8ef2463ff4a336940bc993", "packages": [ { "name": "mustangostang/spyc", @@ -53,6 +53,54 @@ ], "time": "2013-02-21T10:52:01+00:00" }, + { + "name": "paragonie/random_compat", + "version": "v2.0.11", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8", + "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ], + "time": "2017-09-27T21:40:39+00:00" + }, { "name": "simplepie/simplepie", "version": "1.5", @@ -1543,7 +1591,7 @@ "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, - "prefer-lowest": true, + "prefer-lowest": false, "platform": { "php": "^5.6 || ^7.0" }, -- cgit v1.2.1 From 7d9e7183cbc189c356a9bff5d640706959eca1ee Mon Sep 17 00:00:00 2001 From: nashe Date: Tue, 2 Jan 2018 19:35:48 +0100 Subject: Safely generate random HMAC keys for CSRF tokens --- app/classes/CSRF.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/classes/CSRF.php b/app/classes/CSRF.php index 3e23380..639f573 100644 --- a/app/classes/CSRF.php +++ b/app/classes/CSRF.php @@ -5,6 +5,9 @@ class CSRF /** @var string */ const HMAC_ALGORITHM = 'sha1'; + /** @var string */ + const SESSION_KEY_NAME = '_csrf_key'; + /** * Ensure that a CSRF token is valid for a given action. * @@ -44,6 +47,9 @@ class CSRF */ public static function getKey() { - return session_id(); + if (empty($_SESSION[self::SESSION_KEY_NAME])) { + $_SESSION[self::SESSION_KEY_NAME] = random_bytes(16); + } + return $_SESSION[self::SESSION_KEY_NAME]; } } -- cgit v1.2.1