Security Settings:

xmlrpc deaktivieren
 Autorenscan deaktivieren
 Scripting in /wp-content/uploads/ deaktivieren
 Zugriff auf potenziell sensible Dateien blockieren
 Dateieditor im WP Dashboard deaktivieren
 Skriptverkettung deaktivieren
 Skriptausführung im Include-Verzeichnis deaktivieren
 Zugriff von ungewollten Bots verbieten
 Auflistung von Verzeichnissen deaktivieren
 Debug-Ausgaben deaktivieren
 Login-URL ändern
This commit is contained in:
2024-02-21 21:31:00 +01:00
parent 69322d64f3
commit 80fb6cd452
22 changed files with 1062 additions and 370 deletions

View File

@ -4,18 +4,15 @@ namespace Bdp\Modules\Security;
use ZipArchive;
class Security
{
public const required_security_plugins = [
'wps_hide_login' => ['downloadUrl' => 'https://downloads.wordpress.org/plugin/wps-hide-login.1.9.10.zip'],
'limit-login-attempts-reloaded' => ['downloadUrl' => 'https://downloads.wordpress.org/plugin/limit-login-attempts-reloaded.2.25.27.zip']];
public const required_security_plugins = [];
public const delete_plugins = [
'akismet/akismet.php',
'hello.php'
'hello.php',
'wps_hide_login',
'limit-login-attempts-reloaded'
];
public static function setup()
@ -27,9 +24,17 @@ class Security
}
}
$loginUrl = get_option('whl_page', 'bdp_login');
update_option('whl_page', $loginUrl);
$loginUrl = get_option('whl_page', null) ?? 'bdp-login';
enable_option_rewrite_url($loginUrl);
enable_option_disable_xmlrpc();
enable_option_block_authorscan();
enable_option_block_execution_in_uploads();
enable_option_prohibit_special_files();
enable_option_file_editor();
enable_option_disable_conatenation();
enable_option_secure_include_dir();
enable_option_prohibit_bot_access();
enable_option_block_directory_listing();
}
public static function deletePlugins() {
@ -37,6 +42,67 @@ class Security
delete_plugins(self::delete_plugins);
}
public static function ProhibitBots() {
$botList = get_prohibitedbot_list();
if (!is_bot_access_prohibited() || count($botList) == 0) {
return;
}
foreach ($botList as $botListEntry) {
if (stripos($_SERVER['HTTP_USER_AGENT'], $botListEntry) !== false) {
status_header(403);
die();
}
}
}
public static function protectAuthorScan()
{
global $wp;
if (str_starts_with($wp->request, 'author/') && is_authorscan_blocked()) {
status_header(403);
die();
}
}
public static function SetPageFilters() {
global $wp;
if (str_contains($_SERVER['REQUEST_URI'], 'wp-login.php?action=logout')) {
return;
}
add_action('template_redirect', [Security::class, 'protectAuthorScan']);
Security::protectLoginSecurity();
}
public static function protectLoginSecurity() {
$hideLogin = is_login_rewritten();
if (null === $hideLogin) {
return;
}
if ( str_contains( $_SERVER['REQUEST_URI'], 'wp-login.php' ) && ! isset( $_POST['redirect_to'] ) && $_POST['redirect_to'] !== 'interner-bereich' ) {
wp_redirect( home_url() );
die();
}
if ( str_contains( $_SERVER['REQUEST_URI'], $hideLogin ) !== false ) {
$user_login = '';
$_REQUEST['redirect_to'] = 'interner-bereich';
require_once 'wp-login.php';
die();
}
if ( str_contains( $_SERVER['REQUEST_URI'], 'interner-bereich' ) !== false ) {
wp_redirect( '/wp-admin' );
die();
}
}
public static function installSecurityPlugin(string $pluginSlug, string $downloadUrl) : bool
{

View File

@ -0,0 +1,79 @@
<?php
use Bdp\Libs\FileAccess as FileAccess;
use Bdp\Libs\WpConfigEditor as WpConfigEditor;
function is_xmlrpc_disabled() : bool {
return FileAccess::htaccessContains(_protect_wp_disablexmlrpc_string());
}
function is_authorscan_blocked() : bool {
return get_option('protect_wp_hide_authors', false);
}
function is_execution_in_uploads_blocked() : bool {
return FileAccess::htaccessContains(_protect_wp_disable_script_execution_string(), FileAccess::HTACCESS_UPLOADS);
}
function is_access_for_special_files_prohibited() : bool {
return FileAccess::htaccessContains(_protect_wp_disable_special_files_string());
}
function is_file_editor_diabled() : bool {
$isDisabled = WpConfigEditor::getConfigValue('DISALLOW_FILE_EDIT');
if (null == $isDisabled) {
return false;
}
if ('false' == $isDisabled) {
return false;
}
return true;
}
function is_conatenation_disabled() : bool {
$isDisabled = WpConfigEditor::getConfigValue('CONCATENATE_SCRIPTS');
if (null == $isDisabled) {
return false;
}
if ('false' == $isDisabled) {
return false;
}
return true;
}
function is_includedir_protected() : bool {
return FileAccess::htaccessContains(_protect_wp_secure_include_dir_string());
}
function is_directory_listing_disabled() : bool {
return FileAccess::htaccessContains(_protect_wp_disable_directory_listing_string());
}
function is_bot_access_prohibited() : bool {
return get_option('protect_wp_prohibit_bot_access', false);
}
function get_prohibitedbot_list() {
$returnValue = [];
$botList = get_option('protect_wp_prohibit_bot_list', null);
if ($botList !== null) {
$returnValue = unserialize(trim($botList));
}
return $returnValue;
}
function is_wp_debug_diabled() : bool
{
$wpDebugValue = WpConfigEditor::getConfigValue('WP_DEBUG');
return ('false' == $wpDebugValue || null == $wpDebugValue);
}
function is_login_rewritten() : ?string
{
return get_option('kompass_sec_rewrite_login', null);
}

View File

@ -0,0 +1,160 @@
<?php
use Bdp\Libs\FileAccess as FileAccess;
use Bdp\Libs\WpConfigEditor as WpConfigEditor;
function disable_option_disable_xmlrpc() {
return FileAccess::deleteFromHtaccess(_protect_wp_disablexmlrpc_string());
}
function enable_option_disable_xmlrpc() : bool {
return FileAccess::insertInHtaccess(_protect_wp_disablexmlrpc_string());
}
function enable_option_block_authorscan() {
update_option('protect_wp_hide_authors', true);
}
function disable_option_block_authorscan() {
update_option('protect_wp_hide_authors', false);
}
function disable_option_block_execution_in_uploads() {
return FileAccess::deleteFromHtaccess(_protect_wp_disable_script_execution_string(), FileAccess::HTACCESS_UPLOADS);
}
function enable_option_block_execution_in_uploads() {
return FileAccess::insertInHtaccess(_protect_wp_disable_script_execution_string(), FileAccess::HTACCESS_UPLOADS);
}
function disable_option_prohibit_special_files() {
return FileAccess::deleteFromHtaccess(_protect_wp_disable_special_files_string());
}
function enable_option_prohibit_special_files() {
return FileAccess::insertInHtaccess(_protect_wp_disable_special_files_string());
}
function disable_option_file_editor() {
return WpConfigEditor::updateConfig('DISALLOW_FILE_EDIT', 'false');
}
function enable_option_file_editor() {
return WpConfigEditor::updateConfig('DISALLOW_FILE_EDIT', 'true');
}
function enable_option_disable_conatenation() {
return WpConfigEditor::updateConfig('CONCATENATE_SCRIPTS', 'true');
}
function disable_option_disable_conatenation() {
return WpConfigEditor::updateConfig('CONCATENATE_SCRIPTS', 'false');
}
function disable_option_secure_include_dir() {
return FileAccess::deleteFromHtaccess(_protect_wp_secure_include_dir_string());
}
function enable_option_secure_include_dir() : bool {
return FileAccess::insertInHtaccess(_protect_wp_secure_include_dir_string());
}
function enable_option_prohibit_bot_access() {
update_option('protect_wp_prohibit_bot_access', true);
}
function disable_option_prohibit_bot_access() {
update_option('protect_wp_prohibit_bot_access', false);
if (count(get_prohibitedbot_list()) == 0) {
set_prohibitedbot_list(_protect_wp_initial_bot_list_array());
}
}
function set_prohibitedbot_list($botList) {
update_option('protect_wp_prohibit_bot_list', serialize($botList));
}
function enable_option_block_directory_listing() : bool {
return FileAccess::insertInHtaccess(_protect_wp_disable_directory_listing_string());
}
function disable_option_block_directory_listing() : bool {
return FileAccess::deleteFromHtaccess(_protect_wp_disable_directory_listing_string());
}
function enable_option_disable_wp_debug() {
WpConfigEditor::updateConfig('WP_DEBUG', 'false');
}
function disable_option_disable_wp_debug() {
WpConfigEditor::updateConfig('WP_DEBUG', 'true');
}
function enable_option_rewrite_url(?string $url = null) {
global $_POST;
$saveUrl = $url ?? $_POST['rewrite_login'];
update_option('kompass_sec_rewrite_login', $saveUrl);
}
function disable_option_rewrite_url() {
update_option('kompass_sec_rewrite_login', null);
}
function kompass_sec_save_settings($settings) {
$allPossibleSettings = [
'option_disable_xmlrpc',
'option_block_authorscan',
'option_block_execution_in_uploads',
'option_prohibit_special_files',
'option_file_editor',
'option_disable_conatenation',
'option_secure_include_dir',
'option_prohibit_bot_access',
'option_block_directory_listing',
'option_disable_wp_debug',
'option_rewrite_url',
];
$enableSettings = array_intersect($allPossibleSettings, $settings);
$disableSettings = array_diff($allPossibleSettings, $settings);
foreach ($disableSettings as $curSetting) {
$function = 'disable_' . $curSetting;
$function();
}
foreach ($enableSettings as $curSetting) {
$function = 'enable_' . $curSetting;
$function();
}
?>
<div class="notice notice-success">
<p>
<?= __('All settings are saved.', BDP_LV_PLUGIN_SLUG); ?>
</p>
</div>
<?php
return;
}
function kompass_sec_site_keys() {
$content = wp_remote_get('https://api.wordpress.org/secret-key/1.1/salt/');
if (!is_array($content) || !isset($content['body'])) {
?>
<div class="notice notice-error">
<p>
<?= __('An error occured connecting api.wordpress.org', BDP_LV_PLUGIN_SLUG); ?>
</p>
</div>
<?php
return;
}
WpConfigEditor::updateSiteKeys($content['body']);
?>
<div class="notice notice-success">
<p>
<?= __('The site keys were updated successfully.', BDP_LV_PLUGIN_SLUG); ?>
</p>
</div>
<?php
}

View File

@ -0,0 +1,22 @@
<h2><?= __('Bot Detection Database', BDP_LV_PLUGIN_SLUG); ?></h2>
<div class="pwp_setting_box">
<h3><?= __('Registered bots', BDP_LV_PLUGIN_SLUG); ?></h3>
<?php
foreach (get_prohibitedbot_list() as $currenBot) {
?>
<p style=" margin: 10px auto; width: 80%;">
<input type="text" name="existing_bots[]" value="<?= $currenBot ?>" style="width: 100%;" /><br />
<label style="cursor: default; color: #a0a0a0; fot-size: 9pt; font-style: italic"><?= __('Leave blank in order to delete', BDP_LV_PLUGIN_SLUG); ?></label>
</p>
<?php
}
?>
</div>
<div class="pwp_setting_box">
<h3><?= __('Add more bots', BDP_LV_PLUGIN_SLUG); ?></h3>
<p style=" margin: 10px auto; width: 80%;">
<textarea placeholder="<?= __('Please use line breaks to enter multiple bots', BDP_LV_PLUGIN_SLUG); ?>" name="new_bots[]" style="width: 100%;" rows="10"></textarea>
</p>
</div>
<br /><br />
<input type="submit" class="button" value="<?= __('Save changes', BDP_LV_PLUGIN_SLUG); ?>" />

View File

@ -1,6 +1,6 @@
<?php
echo '<div class="health-check-body health-check-debug-tab hide-if-no-js">';
echo '<h1>Erweiterte Sicherheitseinstellungen</h1>';
echo '<h2>Erweiterte Sicherheitseinstellungen</h2>';
if (isset($_POST['submit'])) {
echo '<div id="bdp_success">Die Einstellungen wurden gespeichert.</div>';
update_option('whl_page', $_POST['login_url']);
@ -9,13 +9,12 @@ if (isset($_POST['submit'])) {
<form method="post" action="admin.php?page=bdp-kompass%2Fmodules%2Findex.php&loadmodule=security">
<div class="bdp_security_outer">
<fieldset class="bdp_security_inner">
<legend>Wordpress-Login</legend>
<table>
<table>
<tr style="vertical-align: top;">
<td>Login-URL:</td>
<td> <label><?php echo get_site_url(); ?>/</label><input style="width: 100px;" class="long_text" type="text" name="login_url" id="login_url" required
<td style="font-weight: bold; padding-right: 10px;"><br />Login-URL:</td>
<td style="vertical-align: top;">
<label>
<?php echo get_site_url(); ?>/</label><input style="width: 100px;" class="long_text" type="text" name="login_url" id="login_url" required
value = "<?php echo get_option('whl_page', 'bdp_login'); ?>"
>/<br />
<label style="font-weight: normal; color: #a0a0a0; font-style: italic">
@ -23,9 +22,9 @@ if (isset($_POST['submit'])) {
</label>
</td>
</tr>
</table>
</fieldset>
<input class="bdp_submit" type="submit" name="submit" value="Einstellungen speichern">
</table><br /><br />
<input class="button" type="submit" name="submit" value="Einstellungen speichern">
</div>
</form>

View File

@ -0,0 +1,118 @@
<h2><?= __('Extended Security', BDP_LV_PLUGIN_SLUG); ?></h2>
<div class="bdp_setting_box">
<input <?php if (is_xmlrpc_disabled()) {echo ' checked';} ?> type="checkbox" id="sec_mod_1" name="security_settings[]" value="option_disable_xmlrpc" />
<label for="sec_mod_1">
<?= __('Disable xmlrpc', BDP_LV_PLUGIN_SLUG); ?><br />
<span>
<?= __('By introducing the REST API in WordPress, xmlrpc. However, php is no longer needed to communicate outside of WordPress, which is why there is no longer any reason to leave it active or use it. Therefore, for the security of your site, it is better to deactivate or delete it.', BDP_LV_PLUGIN_SLUG); ?>
</span>
</label>
</div>
<div class="bdp_setting_box">
<input <?php if (is_authorscan_blocked()) {echo ' checked';} ?> type="checkbox" id="sec_mod_2" name="security_settings[]" value="option_block_authorscan" />
<label for="sec_mod_2">
<?= __('Disable Authorscan', BDP_LV_PLUGIN_SLUG); ?><br />
<span>
<?= __('The author page in WordPress typically displays a list of all posts by a specific author on your website. Unfortunately, Google also records the page and to prevent this, we can deactivate the author page. When a visitor clicks on an name of an author, they are redirected to the author page. This page contains a list of posts written by this author, as well as possibly a brief description of the author and a photo. It is also possible to record which user names have been created.', BDP_LV_PLUGIN_SLUG); ?>
</span>
</label>
</div>
<div class="bdp_setting_box">
<input <?php if (is_execution_in_uploads_blocked()) {echo ' checked';} ?> type="checkbox" id="sec_mod_3" name="security_settings[]" value="option_block_execution_in_uploads" />
<label for="sec_mod_3">
<?= __('Disable scripting in /wp-content/uploads/', BDP_LV_PLUGIN_SLUG); ?><br />
<span>
<?= __('Disabling scripting in /wp-content/uploads/ can be a security measure to protect your WordPress website from potential threats. The /wp-content/uploads folder is usually the default folder where WordPress stores uploaded files, such as images, videos, and other media files.', BDP_LV_PLUGIN_SLUG); ?>
</span>
</label>
</div>
<div class="bdp_setting_box">
<input <?php if (is_access_for_special_files_prohibited()) {echo ' checked';} ?> type="checkbox" id="sec_mod_4" name="security_settings[]" value="option_prohibit_special_files" />
<label for="sec_mod_4">
<?= __('Block access to potentially sensitive files', BDP_LV_PLUGIN_SLUG); ?><br />
<span>
<?= __('This setting prohibits access to configuration files and log files', BDP_LV_PLUGIN_SLUG); ?>
</span>
</label>
</div>
<div class="bdp_setting_box">
<input <?php if (true === is_file_editor_diabled()) {echo ' checked';} ?> type="checkbox" id="sec_mod_5" name="security_settings[]" value="option_file_editor" />
<label for="sec_mod_5">
<?= __('Disable file editor in WP Dashboard', BDP_LV_PLUGIN_SLUG); ?><br />
<span>
<?= __('This is a security feature that allows you to prevent users from editing theme and plugin files directly from the WordPress dashboard. This can be useful for a variety of reasons, including preventing accidental code changes and protecting your website from malicious attacks.', BDP_LV_PLUGIN_SLUG); ?>
</span>
</label>
</div>
<div class="bdp_setting_box">
<input <?php if (true === is_conatenation_disabled()) {echo ' checked';} ?> type="checkbox" id="sec_mod_6" name="security_settings[]" value="option_disable_conatenation" />
<label for="sec_mod_6">
<?= __('Disable script concatenation', BDP_LV_PLUGIN_SLUG); ?><br />
<span>
<?= __('Disabling script concatenation in the WordPress admin panel is a simple and effective way to enhance performance. However, it is crucial to carefully consider the impact of this change, as it may increase the number of HTTP requests, potentially affecting loading times', BDP_LV_PLUGIN_SLUG); ?>
</span>
</label>
</div>
<div class="bdp_setting_box">
<input <?php if (true === is_includedir_protected()) {echo ' checked';} ?> type="checkbox" id="sec_mod_7" name="security_settings[]" value="option_secure_include_dir" />
<label for="sec_mod_7">
<?= __('Disable script execution in include dir', BDP_LV_PLUGIN_SLUG); ?><br />
<span>
<?= __('Limiting script execution in specific directories can improve security by preventing potentially malicious scripts from running in critical parts of the WordPress system. This is particularly important to prevent attacks such as Cross-Site Scripting (XSS), which inject malicious code into website content.', BDP_LV_PLUGIN_SLUG); ?>
</span>
</label>
</div>
<div class="bdp_setting_box">
<input <?php if (true === is_bot_access_prohibited()) {echo ' checked';} ?> type="checkbox" id="sec_mod_8" name="security_settings[]" value="option_prohibit_bot_access" />
<label for="sec_mod_8">
<?= __('Prohibit access from unwanted bots', BDP_LV_PLUGIN_SLUG); ?><br />
<span>
<?= __('Excluding specific bots from a WordPress website provides improved security by reducing potentially malicious activity and security risks, optimizes resource consumption and site performance, protects against content theft and duplicate content, enables more precise control of traffic, and promotes more effective SEO -Optimization by reducing irrelevant bots, ultimately leading to a safer, more efficient and better performing website.', BDP_LV_PLUGIN_SLUG); ?><br />
<a href="site-health.php?tab=bdp_enhanced_security&subpage=botlist"><?= __('Bot Detection Database', BDP_LV_PLUGIN_SLUG); ?></a>
</span>
</label>
</div>
<div class="bdp_setting_box">
<input <?php if (true === is_directory_listing_disabled()) {echo ' checked';} ?> type="checkbox" id="sec_mod_9" name="security_settings[]" value="option_block_directory_listing" />
<label for="sec_mod_9">
<?= __('Disable directory listing', BDP_LV_PLUGIN_SLUG); ?><br />
<span>
<?= __('Directory listing should be disabled to ensure the security and privacy of a website. When Directory Listing is enabled, this allows users to directly access the contents of directories on a web server without having to specify a specific file. This can expose sensitive information such as directory structures, internal files and scripts, posing a potential security risk. Disabling Directory Listing prevents users from accessing this sensitive information, thereby providing an additional layer of security for the website.', BDP_LV_PLUGIN_SLUG); ?>
</span>
</label>
</div>
<div class="bdp_setting_box">
<input <?php if (true === is_wp_debug_diabled()) {echo ' checked';} ?> type="checkbox" id="sec_mod_10" name="security_settings[]" value="option_disable_wp_debug" />
<label for="sec_mod_10">
<?= __('Disable debug output', BDP_LV_PLUGIN_SLUG); ?><br />
<span>
<?= __('Debugging should be disabled to protect sensitive information about the internal structure and potential security vulnerabilities of a a WordPress website from potential attackers. When debugging is enabled, error messages and warnings are displayed directly on the website, which can provide attackers with valuable information about the configuration of the website and possible vulnerabilities.', BDP_LV_PLUGIN_SLUG); ?>
</span>
</label>
</div>
<div class="bdp_setting_box">
<input <?php if (null !== is_login_rewritten()) {echo ' checked';} ?> type="checkbox" id="sec_mod_11" name="security_settings[]" value="option_rewrite_url" />
<label for="sec_mod_11">
<?= __('Change Login URL', BDP_LV_PLUGIN_SLUG); ?><br />
<span>
<?= __('Changing the default login URL of WordPress is advisable to enhance the security of your website. By default, WordPress login URLs is /wp-admin or /wp-login.php, which are easily guessed by hackers and facilitate attacks such as brute-force attacks. Changing the login URL to something unique and difficult to guess increases security since potential attackers will struggle to find the correct URL. This can help protect your website from unauthorized access and other malicious activities.', BDP_LV_PLUGIN_SLUG); ?><br />
<label style="font-weight: bold;">
<?= __('Login-URL', BDP_LV_PLUGIN_SLUG) ?>: <?= get_site_url(); ?>/<input style="width: 100px;" class="long_text" type="text" name="rewrite_login" id="rewrite_login" value="<?= is_login_rewritten(); ?>">
</label>
</span>
</label>
</div>
<br /><br />
<input type="submit" class="button" value="<?= __('Save changes', BDP_LV_PLUGIN_SLUG); ?>" />
<a class="button" href="site-health.php?tab=bdp_enhanced_security&action=updatesitekeys"><?= __('Change site keys', BDP_LV_PLUGIN_SLUG); ?></a>

View File

@ -1,21 +1,53 @@
<?php
require_once dirname(__FILE__) . '/includes/settings_reader.php';
require_once dirname(__FILE__) . '/includes/settings_writer.php';
function wp_example_site_health_navigation_tabs( $tabs ) {
// translators: Tab heading for Site Health navigation.
$tabs['loginurl'] = esc_html_x( 'Login-URL', 'Site Health', 'text-domain' );
$tabs['bdp_enhanced_security'] = esc_html_x('Erweiterte Sicherheit', 'Site Health', 'text-domain');
return $tabs;
}
add_filter( 'site_health_navigation_tabs', 'wp_example_site_health_navigation_tabs' );
function wp_example_site_health_tab_content($tab)
{
// Do nothing if this is not our tab.
if ('loginurl' === $tab) {
require_once dirname(__FILE__) . '/internal/index.php';
return;
}
if ('bdp_enhanced_security' === $tab) {
if (isset($_GET['subpage']) && $_GET['subpage'] == 'botlist') {
if (isset($_POST['save_settings']) && isset($_POST['existing_bots']) && isset($_POST['new_bots'])) {
protect_wp_save_bots($_POST['existing_bots'], $_POST['new_bots']);
}
echo '<div class="health-check-body health-check-status-tab hide-if-no-js">';
echo '<form method="post" action="site-health.php?tab=' . BDP_LV_PLUGIN_SLUG . '&subpage=botlist">';
echo '<input type="hidden" name="save_settings" value="true" />';
require BDP_LV_PLUGIN_DIR . 'modules/security/internal/botlist-tab.php';
echo '</form>';
echo '</div>';
return;
}
update_option('protect_wp_needs_attention', false);
if (isset($_POST['save_settings'])) {
$securitySettings = [];
if (isset($_POST['security_settings'])) {
$securitySettings = $_POST['security_settings'];
}
kompass_sec_save_settings($securitySettings);
}
if (isset($_GET['action']) && $_GET['action'] == 'updatesitekeys') {
kompass_sec_site_keys();
}
echo '<div class="health-check-body health-check-status-tab hide-if-no-js">';
echo '<form method="post" action="site-health.php?tab=bdp_enhanced_security">';
echo '<input type="hidden" name="save_settings" value="true" />';
require BDP_LV_PLUGIN_DIR . 'modules/security/internal/site-health-tab.php';
echo '</form>';
echo '</div>';
return;
}
}
add_action('site_health_tab_content', 'wp_example_site_health_tab_content');