Skip to content

Commit

Permalink
Merge branch 'release-0.12'
Browse files Browse the repository at this point in the history
  • Loading branch information
chesio committed Mar 5, 2019
2 parents 88b5fe7 + e1f965b commit 382201c
Show file tree
Hide file tree
Showing 15 changed files with 372 additions and 200 deletions.
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/.gitattributes export-ignore
/.gitignore export-ignore
/phpcs.xml export-ignore
/tests export-ignore
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Helps keeping WordPress websites secure.
## Limitations

* BC Security has not been tested on WordPress multisite installation.
* BC Security is primarily being developed for Apache webserver and Unix-like environments.
* BC Security has not been tested on Windows server.

## Setup

Expand All @@ -35,6 +35,7 @@ Basic checks cover common security practices. They do not require any informatio
1. Is error log file not publicly available? This check is only run if both `WP_DEBUG` and `WP_DEBUG_LOG` constants are set to true.
1. Are there no common usernames like admin or administrator on the system?
1. Are user passwords hashed with some non-default hashing algorithm?
1. Is PHP version still supported?

#### Advanced checks

Expand Down
2 changes: 1 addition & 1 deletion bc-security.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Author URI: https://www.chesio.com
* Requires PHP: 7.1
* Requires WP: 4.9
* Tested up to: 4.9
* Tested up to: 5.1
* Text Domain: bc-security
* GitHub Plugin URI: https://github.com/chesio/bc-security
*/
Expand Down
33 changes: 22 additions & 11 deletions classes/BlueChip/Security/Core/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,28 @@ public function reset(): bool
}


/**
* Remove the data from database (= hard reset).
*
* @return bool True, if settings have been deleted, false otherwise.
*/
public function destroy(): bool
{
return delete_option($this->option_name);
}


/**
* Persist the value of data into database.
*
* @return bool True, if settings have been updated (= changed), false otherwise.
*/
public function persist(): bool
{
return update_option($this->option_name, $this->data);
}


/**
* Sanitize $settings array: only keep known keys, provide default values for missing keys.
*
Expand Down Expand Up @@ -254,17 +276,6 @@ protected static function parseList($list): array
}


/**
* Persist the value of data into database.
*
* @return bool True, if settings have been updated (= changed), false otherwise.
*/
protected function persist(): bool
{
return update_option($this->option_name, $this->data);
}


/**
* Update setting under $name with $value. Store update values in DB.
*
Expand Down
21 changes: 20 additions & 1 deletion classes/BlueChip/Security/Helpers/FormHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@

abstract class FormHelper
{
/**
* @link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea
* @var int Default value of "cols" attribute of <textarea> element.
*/
const TEXTAREA_COLS_DEFAULT_VALUE = 20;

/**
* @var int Maximum for content-based value of "rows" attribute of <textarea> element.
*/
const TEXTAREA_ROWS_MAXIMUM_VALUE = 20;

/**
* @var int Minimum for content-based value of "rows" attribute of <textarea> element.
*/
const TEXTAREA_ROWS_MINIMUM_VALUE = 4;


/**
* Print <input type="checkbox" /> element.
*
Expand Down Expand Up @@ -120,7 +137,7 @@ public static function printSelect(array $args)
*
* Note: method expects the value argument `$args['value']` to be an array (of lines).
*
* @param array $args Required: label_for, name, value. Optional: class.
* @param array $args Required: label_for, name, value. Optional: class, cols, rows.
*/
public static function printTextArea(array $args)
{
Expand All @@ -129,6 +146,8 @@ public static function printTextArea(array $args)
'class' => $args['class'] ?? '',
'id' => $args['label_for'],
'name' => $args['name'],
'cols' => $args['cols'] ?? self::TEXTAREA_COLS_DEFAULT_VALUE,
'rows' => $args['rows'] ?? max(min(count($args['value']), self::TEXTAREA_ROWS_MAXIMUM_VALUE), self::TEXTAREA_ROWS_MINIMUM_VALUE),
];

echo '<textarea ' . self::renderFieldProperties($properties) . '>';
Expand Down
10 changes: 10 additions & 0 deletions classes/BlueChip/Security/Helpers/Is.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/**
* @package BC_Security
*/

namespace BlueChip\Security\Helpers;

/**
Expand All @@ -24,6 +25,15 @@ public static function admin(\WP_User $user): bool
}


/**
* @return bool True, if current webserver interface is CLI, false otherwise.
*/
public static function cli(): bool
{
return php_sapi_name() === 'cli';
}


/**
* Return true, if current request is of given $type.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class AutorunSettings extends \BlueChip\Security\Core\Settings
Checks\ErrorLogNotPubliclyAccessible::class => false,
Checks\NoObviousUsernamesCheck::class => false,
Checks\NoMd5HashedPasswords::class => false,
Checks\PhpVersionSupported::class => false,
Checks\NoPluginsRemovedFromDirectory::class => false,
Checks\CoreIntegrity::class => false,
Checks\PluginsIntegrity::class => false,
Expand Down
12 changes: 10 additions & 2 deletions classes/BlueChip/Security/Modules/Checklist/Check.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ protected function __construct(string $name, string $description)
{
$this->name = $name;
$this->description = $description;
$this->last_run = Transients::getForSite(self::LAST_RUN_TRANSIENT_ID, self::getId()) ?: 0;
$this->result = Transients::getForSite(self::RESULT_TRANSIENT_ID, self::getId()) ?: new CheckResult(null, '<em>' . esc_html__('Check has not been run yet or the bookkeeping data has been lost.', 'bc-security') . '</em>');
$this->last_run = null; // Is lazy-loaded.
$this->result = null; // Is lazy-loaded.
}


Expand Down Expand Up @@ -88,6 +88,10 @@ public function getName(): string
*/
public function getTimeOfLastRun(): int
{
if ($this->last_run === null) {
$this->last_run = Transients::getForSite(self::LAST_RUN_TRANSIENT_ID, self::getId()) ?: 0;
}

return $this->last_run;
}

Expand All @@ -97,6 +101,10 @@ public function getTimeOfLastRun(): int
*/
public function getResult(): CheckResult
{
if ($this->result === null) {
$this->result = Transients::getForSite(self::RESULT_TRANSIENT_ID, self::getId()) ?: new CheckResult(null, '<em>' . esc_html__('Check has not been run yet or the bookkeeping data has been lost.', 'bc-security') . '</em>');
}

return $this->result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ private static function findUnknownFiles($checksums): array
Checklist\Hooks::IGNORED_CORE_UNKNOWN_FILES,
[
'.htaccess',
'composer.json', // WordPress might be installed via Composer
'wp-config.php',
'liesmich.html', // German readme (de_DE)
'olvasdel.html', // Hungarian readme (hu_HU)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php
/**
* @package BC_Security
*/

namespace BlueChip\Security\Modules\Checklist\Checks;

use BlueChip\Security\Modules\Checklist;

class PhpVersionSupported extends Checklist\BasicCheck
{
/**
* @var array List of supported PHP versions and their end-of-life dates
*/
const SUPPORTED_VERSIONS = [
'7.1' => '2019-12-01',
'7.2' => '2020-10-30',
'7.3' => '2021-12-06',
];


public function __construct()
{
parent::__construct(
__('PHP version is supported', 'bc-security'),
sprintf(__('Running an <a href="%s">unsupported PHP version</a> may pose a security risk.', 'bc-security'), 'https://secure.php.net/supported-versions.php')
);
}


protected function runInternal(): Checklist\CheckResult
{
// Get oldest supported version (as <major>.<minor>):
$oldest_supported_version = self::getOldestSupportedPhpVersion();

if (is_null($oldest_supported_version)) {
$message = sprintf(
esc_html__('List of supported PHP versions is out-dated. Consider updating the plugin. Btw. you are running PHP %1$s.', 'bc-security'),
self::formatPhpVersion()
);
return new Checklist\CheckResult(null, $message);
}

// Get active PHP version as <major>.<minor> string:
$php_version = sprintf("%s.%s", PHP_MAJOR_VERSION, PHP_MINOR_VERSION);

if (version_compare($php_version, $oldest_supported_version, '>=')) {
// PHP version is supported, but do we have end-of-life date?
$eol_date = self::SUPPORTED_VERSIONS[$php_version] ?? null;
// Format message accordingly.
$message = $eol_date
? sprintf(
esc_html__('You are running PHP %1$s, which is supported until %2$s.', 'bc-security'),
self::formatPhpVersion(),
date_i18n(get_option('date_format'), strtotime($eol_date))
)
: sprintf(
esc_html__('You are running PHP %1$s, which is still supported.', 'bc-security'),
self::formatPhpVersion()
)
;
return new Checklist\CheckResult(true, $message);
} else {
$message = sprintf(
esc_html__('You are running PHP %1$s, which is no longer supported! Consider upgrading your PHP version.', 'bc-security'),
self::formatPhpVersion()
);
return new Checklist\CheckResult(false, $message);
}
}


/**
* @return string HTML tag with PHP version as <major>.<minor> string with full version in title attribute.
*/
private static function formatPhpVersion(): string
{
return sprintf('<em title="%s">%s.%s</em>', PHP_VERSION, PHP_MAJOR_VERSION, PHP_MINOR_VERSION);
}


/**
* @return string Oldest supported version of PHP as of today or null, if it can not be determined from data available.
*/
private static function getOldestSupportedPhpVersion(): ?string
{
$now = current_time('timestamp');

foreach (self::SUPPORTED_VERSIONS as $version => $eol_date) {
if (strtotime($eol_date) >= $now) {
return $version;
}
}

return null;
}
}
3 changes: 3 additions & 0 deletions classes/BlueChip/Security/Modules/Checklist/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ public function constructChecks(\wpdb $wpdb): array
// No passwords should be hashed with (default) MD5 hash.
Checks\NoMd5HashedPasswords::getId() => new Checks\NoMd5HashedPasswords($wpdb),

// PHP version should be supported.
Checks\PhpVersionSupported::getId() => new Checks\PhpVersionSupported(),

// There are no modified or unknown WordPress core files.
Checks\CoreIntegrity::getId() => new Checks\CoreIntegrity(),

Expand Down
6 changes: 4 additions & 2 deletions classes/BlueChip/Security/Modules/IpBlacklist/Bouncer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

namespace BlueChip\Security\Modules\IpBlacklist;

use BlueChip\Security\Helpers;

/**
* Bouncer takes care of bouncing uninvited guests by:
* 1) Blocking access to website, if remote IP address cannot be determined.
Expand Down Expand Up @@ -39,8 +41,8 @@ public function __construct(string $remote_address, Manager $bl_manager)
*/
public function load()
{
// If remote IP address is invalid, die immediately.
if (empty($this->remote_address)) {
// In case of non-cli context, if remote IP address is invalid, die immediately.
if (!Helpers\Is::cli() && empty($this->remote_address)) {
self::blockAccessTemporarily();
}

Expand Down
7 changes: 6 additions & 1 deletion classes/BlueChip/Security/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ public function init()
*/
public function activate()
{
// Explicitly persist every setting object, so related option is autoloaded.
foreach ($this->settings as $settings) {
$settings->persist();
}

// Install every module that requires it.
foreach ($this->modules as $module) {
if ($module instanceof Modules\Installable) {
Expand Down Expand Up @@ -233,7 +238,7 @@ public function uninstall()
{
// Remove plugin settings.
foreach ($this->settings as $settings) {
delete_option($settings->getOptionName());
$settings->destroy();
}

// Remove site transients set by plugin.
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.2",
"phpunit/phpunit": "^6.5",
"phpunit/phpunit": "^7.5",
"brain/monkey": "^2.2"
},
"autoload-dev": {
Expand Down
Loading

0 comments on commit 382201c

Please sign in to comment.