*/
/**
* Do not execute this file directly.
*/
if (!defined('ABSPATH')) {
exit;
}
use \blobfolio\wp\meow\about;
use \blobfolio\wp\meow\ajax;
use \blobfolio\wp\meow\core;
use \blobfolio\wp\meow\login;
use \blobfolio\wp\meow\options;
use \blobfolio\wp\meow\vendor\common;
$current_user = wp_get_current_user();
$data = array(
'forms'=>array(
'settings'=>array(
'action'=>'meow_ajax_settings',
'n'=>ajax::get_nonce(),
'errors'=>array(),
'saved'=>false,
'loading'=>false
)
),
'readonly'=>options::get_readonly(),
'section'=>'settings',
'modal'=>false,
// @codingStandardsIgnoreStart
'modals'=>array(
'brute-force'=>array(
sprintf(
esc_html__('%s robots visit WordPress dozens of times each day, attempting to guess their way into wp-admin. WordPress makes no attempt to mitigate this, allowing a single robot to try combination after combination until they succeed.', 'apocalypse-meow'),
'' . esc_html__('Brute-force', 'apocalypse-meow') . ''
),
esc_html__('Apocalypse Meow keeps track of login attempts and will temporarily ban any person or robot who has failed too much, too fast. This is critical set-and-forget protection.', 'apocalypse-meow')
),
'login-fail_limit'=>array(
esc_html__('This is the maximum number of login failures allowed for a given IP before the login process is disabled for that individual.', 'apocalypse-meow')
),
'login-subnet_fail_limit'=>array(
sprintf(
esc_html__('Sometimes attacks come from multiple IPs on the same network. This limit applies to the number of failures attributed to a network subnet (%s for IPv4 and %s for IPv6). It is recommended you set this value 4-5x higher than the individual fail limit.', 'apocalypse-meow'),
'/24',
'/64'
)
),
'login-fail_window'=>array(
esc_html__('An individual IP or entire network subnet will be banned from logging in whenever their total number of failures within this window exceeds the fail limits.', 'apocalypse-meow'),
esc_html__('The ban lasts as long as this is true, and will reset when the earliest of the counted failures grows old enough to fall outside the window. Remaining failures, if any, that are still within the window will continue to be matched against the fail limits.', 'apocalypse-meow'),
esc_html__('For reference, the default value of 720 translates to 12 hours.')
),
'login-reset_on_success'=>array(
esc_html__('When someone successfully logs in, their prior failures are no longer counted against them, even if those failures are still within the window.', 'apocalypse-meow'),
),
'login-key'=>array(
sprintf(
esc_html__("Most servers report the remote visitor's IP address using the %s key, but if yours is living behind a proxy, the IP information might live somewhere else. If you aren't sure what to do, look for your IP address in the list.", 'apocalypse-meow'),
'REMOTE_ADDR'
),
esc_html__('Note: visitor IP information forwarded from a proxy is not trustworthy because it is populated via request headers, which can be forged. Depending on the setup of your particular environment, this may make it impossible to effectively mitigate brute-force attacks.', 'apocalypse-meow')
),
'login-exempt'=>array(
esc_html__('It is very important you avoid getting yourself or your coworkers banned (the latter happens frequently in office environments where multiple employees fail around the same time). You should whitelist any IP addresses, ranges, or subnets from which you will be connecting.', 'apocalypse-meow'),
),
'login-nonce'=>array(
sprintf(
esc_html__('This option adds a hidden field to the standard %s form to help ensure that login attempts are actually originating there (rather than coming out of the blue, as is typical of robotic assaults).', 'apocalypse-meow'),
'wp-login.php'
),
esc_html__('*Do not* enable this option if your site uses custom login forms or if the login page is cached.', 'apocalypse-meow'),
esc_html__('Note: stale cookies from past visits might ocassionally trigger a Nonce failure on the first login attempt. WordPress should refresh the Nonce value during that first post, so it should work on the second go-around.', 'apocalypse-meow')
),
'login-alert_on_new'=>array(
esc_html__('This will send an email to the account user whenever access is granted to an IP address that has not successfully logged in before.', 'apocalypse-meow'),
esc_html__('Note: this depends on the data logged by the plugin, so if you have configured a short retention time, it may not be very useful.', 'apocalypse-meow')
),
'login-alert_by_subnet'=>array(
esc_html__('This will cause the email alert function to use subnets rather than individual IPs when determining "newness". This setting is recommended for IPv6 users in particular as their IPs will change frequently.', 'apocalypse-meow'),
),
'passwords'=>array(
esc_html__('Strong, unique passwords are critical for security. For historical reasons, WordPress still allows users to choose unsafe passwords for themselves. These options set some basic boundaries.', 'apocalypse-meow'),
esc_html__('Note: because WordPress passwords are encrypted, it is not possible to apply these settings retroactively. However when users log in, if their passwords are unsafe, they will be directed to change it.')
),
'password-alpha'=>array(
esc_html__('Whether or not a password must have letters in it. The third option, "UPPER & lower", requires a password contain a mixture of both upper- and lowercase letters.', 'apocalypse-meow'),
),
'password-numeric'=>array(
esc_html__('Whether or not a password must have numbers in it.', 'apocalypse-meow'),
),
'password-symbol'=>array(
esc_html__('Whether or not a password must have non-alphanumeric characters in it, like a cartoon curse word: $!#*()%.', 'apocalypse-meow'),
),
'password-length'=>array(
esc_html__("This sets a minimum length requirement for passwords. The plugin's own minimum minimum (how low you are allowed to set it) is subject to change as technology advances. If your entry falls below the times, it will be adjusted automatically.", 'apocalypse-meow'),
),
'password-common'=>array(
esc_html__('Apocalypse Meow automatically prevents users from choosing any of the top 100K most common passwords. This protection is mandatory and cannot be disabled. ;)', 'apocalypse-meow'),
),
'core'=>array(
esc_html__('Out-of-the-Box, certain WordPress features and frontend oversights on the part of theme and plugin developers, can inadvertently place sites at greater risk of being successfully exploited by a hacker.', 'apocalypse-meow'),
esc_html__('Please make sure you read about each option before flipping any switches. While each of these items mitigates a threat, some threats are more threatening than others, and if your workflow depends on something you disable here, that might make life sad.', 'apocalypse-meow')
),
'core-wp_rest'=>array(
sprintf(
esc_html__('%s is a new feature within WordPress that provides %s API access to view or update site content. Depending on who you ask, this is either a dream come true or a complete shitshow.', 'apocalypse-meow'),
'WP-REST',
'RESTful'
),
esc_html__("But hackers universally love it. Not only does it vastly streamline reconnaissance, it also extends the software's attack surface, providing all new avenues for exploitation.", 'apocalypse-meow'),
esc_html__("WordPress no longer allows WP-REST to be fully disabled, so Apocalypse Meow gives you the next best thing: the ability to restrict *access* to it. If you aren't using this feature at all, please set the access to \"Nobody\" to limit your exposure.", 'apocalypse-meow')
),
'template-adjacent_posts'=>array(
esc_html__("WordPress adds information about next and previous posts in the HTML
DISALLOW_FILE_EDIT'
)
),
'template-generator_tag'=>array(
esc_html__('By default, WordPress embeds a version tag in the HTML . While this information is largely innocuous (and discoverable elsewhere), it can help nogoodniks better target attacks against your site. Since this is really only something a robot would see, it is safe to remove.', 'apocalypse-meow')
),
'template-readme'=>array(
esc_html__('WordPress releases include a publicly accessible file detailing the version information. This is one of the first things a hacker will look for as it will help them better target their attacks.', 'apocalypse-meow'),
(
@file_exists(trailingslashit(ABSPATH) . 'readme.html') ? sprintf(
esc_html__('Click %s to view yours.', 'apocalypse-meow'),
'' . esc_html__('here', 'apocalypse-meow') . ''
) : esc_html__('Your site does not have one right now. Woo!', 'apocalypse-meow')
)
),
'template-noopener'=>array(
sprintf(
esc_html__("Any links on your site that open in a new window (e.g. %s) could potentially trigger a redirect in *your* site's window. This opens the door to some sneaky phishing attacks. See %s and %s for more information.", 'apocalypse-meow'),
'target="blank"',
'' . esc_html__('here', 'apocalypse-meow') . '',
'' . esc_html__('here', 'apocalypse-meow') . ''
),
sprintf(
esc_html__("This option adds %s to vulnerable links on your site, which is meant to disable this capability. It is a lightweight and non-destructive approach, but doesn't protect all browsers.", 'apocalypse-meow'),
'rel="noopener"'
),
sprintf(
esc_html__('For a more comprehensive solution, take a look at %s.', 'apocalypse-meow'),
'blankshield'
)
),
'enumeration'=>array(
sprintf(
esc_html__("Ever wonder how a robot guessed your username? There's a neat trick that exploits a weakness in WordPress' permalink rewriting: visit %s and you should be redirected to a pretty URL ending in your username (unless Apocalypse Meow stops it). Robots simply try %s, %s, etc.", 'apocalypse-meow'),
'' . site_url('?author=' . $current_user->ID) . '',
'?author=1',
'?author=2'
),
),
'core-enumeration'=>array(
sprintf(
esc_html__("This setting blacklists the %s query variable so it cannot be used by robots… or anyone. Do not enable this setting if any of your themes or plugins lazy-link to an author's ID instead of their actual archive URL.", 'apocalypse-meow'),
'author'
),
sprintf(
esc_html__('Note: this setting will also disable the WP-REST %s endpoint in WordPress versions 4.7+. To restrict API requests for user information in earlier versions, alter the WP-REST access setting at the top of this section.', 'apocalypse-meow'),
'users'
)
),
'core-enumeration_die'=>array(
sprintf(
esc_html__('By default, this plugin simply redirects any %s requests to the home page. But if you enable this option, it will instead trigger a 400 error and exit. This approach uses fewer resources and can more easily integrate with general log-monitoring policies.', 'apocalypse-meow'),
'?author=X'
),
esc_html__('Note: WP-REST requests will always result in an API error.', 'apocalypse-meow')
),
'core-enumeration_fail'=>array(
esc_html__('When enabled, user enumeration attempts will be counted as login failures. You probably want to enable this as user enumeration usually precedes a login attack.', 'apocalypse-meow'),
sprintf(
esc_html__('For tracking purposes, the "username" for these log entries will always read "%s".', 'apocalypse-meow'),
core::ENUMERATION_USERNAME
),
),
'core-xmlrpc'=>array(
sprintf(
esc_html__("WordPress comes with an %s API to let users manage their blog content from mobile apps and other web sites. This is good stuff, but is also a common (and powerful) entry point for hackers. If you aren't using it, disable it.", 'apocalypse-meow'),
'XML-RPC'
),
sprintf(
esc_html__('Some plugins, like %s, will not work correctly with XML-RPC disabled. If something breaks, just re-enable it.', 'apocalypse-meow'),
'Jetpack'
)
),
'prune'=>array(
esc_html__('Brute-force login prevention relies on record-keeping. Over time, with lots of activity, that data might start to pose storage or performance problems. Apocalypse Meow can be configured to automatically remove old data.', 'apocalypse-meow'),
),
'prune-active'=>array(
esc_html__('Enable this option to ease your server of the burden of keeping indefinite login activity records.', 'apocalypse-meow')
),
'prune-limit'=>array(
esc_html__("Data older than this will be automatically pruned. It's a balance. Don't be too stingy or features like New Login Alerts won't be as effective. For most sites, it is a good idea to maintain at least 3 months worth of data.", 'apocalypse-meow')
)
)
// @codingStandardsIgnoreEnd
);
$options = options::get();
foreach ($options as $k=>$v) {
// Everything but license.
if ('license' === $k) {
continue;
}
// We need to convert any boolean values to integers to keep Vue.js
// happy.
foreach ($v as $k2=>$v2) {
if (is_bool($v2)) {
$v[$k2] = $v2 ? 1 : 0;
}
}
$data['forms']['settings'][$k] = $v;
}
// The fail window gets translated to minutes to make the numbers
// easier to deal with.
$data['forms']['settings']['login']['fail_window'] = ceil($data['forms']['settings']['login']['fail_window'] / 60);
// The whitelist needs to be collapsed.
$data['forms']['settings']['login']['exempt'] = trim(implode("\n", $data['forms']['settings']['login']['exempt']));
// JSON doesn't appreciate broken UTF.
common\ref\sanitize::utf8($data);
?>