*/ /** * 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, ), 'reset'=>array( 'action'=>'meow_ajax_reset', '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-whitelist'=>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-blacklist'=>array( esc_html__('Where there is light, there is darkness. If a particular network is consistently harassing you, you can add their IP address, range, or subnet to the blacklist. Any entry here will never be able to access the login form.', 'apocalypse-meow'), esc_html__("Be very careful! If you do something silly like add yourself to the blacklist, you'll be locked out of the site.", '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'), ), '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-exempt_length'=>array( esc_html__('Pedantic password rules (like all the above) are well and good for short passwords, but really length is key. For users who want to choose a strong passphrase for themselves, such rules just get in the way.', 'apocalypse-meow'), esc_html__('This option sets the minimum length at which a password can be considered exempt from needing specific contents like letters or numbers.', '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'), ), 'password-bcrypt'=>array( sprintf( esc_html__("This option replaces WordPress' password hashing algorithm with the more modern and secure %s. This will help protect your users in the event a hacker gains access to the site database by making the user passwords much more time-consuming to crack.", 'apocalypse-meow'), 'bcrypt' ), esc_html__('There are a few things worth noting:', 'apocalypse-meow'), sprintf( esc_html__('Bcrypt is scalable. When this setting is first enabled, Apocalypse Meow will calculate the best security/performance balance for your server. If you ever change hosting or upgrade the server hardware, just toggle the option %s then back %s to recalibrate.', 'apocalypse-meow'), '' . esc_html__('Disabled', 'apocalypse-meow') . '', '' . esc_html__('Enabled', 'apocalypse-meow') . '' ), esc_html__('This option does not retroactively alter existing password hashes. When enabled, hashes will be updated as each user logs into the site. When disabled, WordPress will dutifully process any logins with bcrypt-hashed passwords, but will not downgrade them.', 'apocalypse-meow'), ), 'password-retroactive'=>array( esc_html__('When enabled, if an existing user logs in with a password that does not meet the current site requirements, they will be redirected to their profile and asked to come up with something stronger.', '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 . This isn't usually a big deal, but can help robots find pages you thought were private. This is just robot food, so you can safely remove it.", 'apocalypse-meow') ), 'core-file_edit'=>array( esc_html__('WordPress comes with the ability to edit theme and plugin files directly through the browser. If an attacker gains access to WordPress, they too can make such changes.', 'apocalypse-meow'), esc_html__('Please just use FTP to push code changes to the site. Haha.', 'apocalypse-meow'), sprintf( esc_html('Note: This will have no effect if the %s constant is defined elsewhere.', 'apocalypse-meow'), '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') ), 'request'=>array( sprintf( esc_html__('The server returns various %s with every HTTP request. This information helps web browsers make sense of the returned content, and can also be used to enable or disable features, some of which have security implications.', 'apocalypse-meow'), '' . esc_html__('headers', 'apocalypse-meow') . '' ), esc_html__('Not all browsers honor or understand all headers, but the settings in this section can help improve the security for users with browsers that do.', 'apocalypse-meow'), ), 'template-referrer_policy'=>array( sprintf( esc_html__('By default, when a visitor clicks a link, the browser will send the URL of the referring page to the new server. For example, if you click %s to learn about the %s header, %s would know you came from %s.', 'apocalypse-meow'), 'here', 'Referrer-Policy', 'blog.appcanary.com', '' . admin_url('admin.php?page=meow-settings') . '' ), sprintf( esc_html__('That is, unless, your server tells it not to (and the browser listens). When set to %s, a policy of %s will be set, sharing only your domain name. When set to %s, a policy of %s will be set, sharing nothing.', 'apocalypse-meow'), '' . esc_html__('Limited', 'apocalypse-meow') . '', 'origin-when-cross-origin', '' . esc_html__('None', 'apocalypse-meow') . '', 'no-referrer' ), sprintf( esc_html__("Referrer Policies can be set in other ways, so if you don't need or want Apocalypse Meow to set any headers at all, leave this option set to %s.", 'apocalypse-meow'), '' . esc_html__('Default', 'apocalypse-meow') . '' ), ), 'template-x_content_type'=>array( sprintf( esc_html__('%s are meant to help software, like web browsers, correctly identify and display files. When the server sends %s, it should send a corresponding %s header identifying it as %s.', 'apocalypse-meow'), '' . esc_html__('MIME types', 'apocalypse-meow') . '', 'kitten.jpg', 'Content-Type', 'image/jpeg' ), sprintf( esc_html__('Unfortunately, MIME handling is %s.', 'apocalypse-meow'), '' . esc_html__('a chaotic mess', 'apocalypse-meow') . '' ), esc_html__('To help work around this, browsers will attempt to intelligently determine what kind of a file it has been given, independently of any headers, and handle it however it chooses.', 'apocalypse-meow'), sprintf( esc_html__('This can be dangerous for WordPress sites, since upload validation is essentially limited to file names alone, which of course are completely arbitrary. If an attacker manages to upload a malicious Flash file by calling it %s, a browser will still send it to the Flash plugin.', 'apocalypse-meow'), 'kitten.jpg' ), sprintf( esc_html__('When enabled, the server will send a %s header with a value of %s. As long as your server correctly identifies its own content, this should be safe to enable.', 'apocalypse-meow'), 'X-Content-Type-Options', 'nosniff' ), ), 'template-x_frame'=>array( sprintf( esc_html__("The %s header tells a browser whether or not pages from your site can be embedded *inside* someone else's. Unless you host content that is specifically intended to be embedded elsewhere, embedding should be disabled to avoid attacks like %s.", 'apocalypse-meow'), 'X-Frame-Options', 'clickjacking' ), sprintf( esc_html__('By default, the WordPress backend sends this header with a value of %s, meaning that admin pages can only be embedded by other pages on your site. This option extends this behavior site-wide.', 'apocalypse-meow'), 'SAMEORIGIN', '<iframe>' ), esc_html__('Unless you host content that is specifically intended to be embedded elsewhere, you should enable this option.', 'apocalypse-meow'), ), 'register'=>array( esc_html__('As you have probably noticed, open WordPress registrations attract a lot of SPAM. The options in this section provide several tests designed to detect and block robot submissions, while remaining entirely invisible to actual humans.', 'apocalypse-meow'), esc_html__('*Do not* enable these options if your site uses custom registration forms or if the registration page is cached.', 'apocalypse-meow'), ), 'register-cookie'=>array( sprintf( esc_html__('Registration robots are often very bare-bones and might not include basic functionality like support for %s.', 'apocalypse-meow'), 'HTTP Cookies' ), esc_html__('This option sets a small cookie when the registration form is first loaded, and checks that it (still) exists when the form is being processed.', 'apocalypse-meow'), esc_html__('This option should be safe to enable on all sites, regardless of user demographic, as cookie support is a fundamental requirement of the WordPress login process.', 'apocalypse-meow'), ), 'register-honeypot'=>array( sprintf( esc_html__('Most SPAM robots are programmed to enter values into every form field they come across. This option uses a hidden text field — a %s that is meant to remain empty — to check for this behavior.', 'apocalypse-meow'), 'honeypot' ), ), 'register-javascript'=>array( sprintf( esc_html__('Registration robots are often very bare-bones and might not include basic functionality like support for %s.', 'apocalypse-meow'), 'Javascript' ), esc_html__('This option uses Javascript to inject a hidden field into the registration form. If a web browser or robot is unable to execute the script, an error will be triggered.', 'apocalypse-meow'), esc_html__('Note: if a human user has chosen to disable Javascript support for whatever reason, this option will prevent them from registering. If your site is specifically designed to work without Javascript support, you should leave this option disabled.', 'apocalypse-meow'), ), 'register-nonce'=>array( esc_html__('This option adds a hidden field to the registration form to help ensure that submissions are actually originating from your site (rather than coming out of the blue, as is typical of robotic assaults).', 'apocalypse-meow'), ), 'register-speed'=>array( esc_html__('When a human completes a form, they will need to spend some amount of time reading, typing, and clicking. Robots, on the other hand, can work much faster. This option adds a speed limit to the registration form, requiring that at least two seconds have elapsed from the time the page was first generated.', 'apocalypse-meow'), ), 'register-jail'=>array( esc_html__('Because WordPress uses the same script for logins and registrations, Apocalypse Meow bans always apply.', 'apocalypse-meow'), esc_html__('This option merely tightens the jail integration by logging registration failures in the main activity table. From there, the usual ban logic applies.', 'apocalypse-meow'), esc_html__('Note: some registration errors are not necessarily malicious in nature and so are ignored by Apocalypse Meow. For example, a user should not be banned simply because each username they think of is already taken. :)', '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 and blacklist need to be collapsed. $data['forms']['settings']['login']['blacklist'] = trim(implode("\n", $data['forms']['settings']['login']['blacklist'])); $data['forms']['settings']['login']['whitelist'] = trim(implode("\n", $data['forms']['settings']['login']['whitelist'])); // JSON doesn't appreciate broken UTF. common\ref\sanitize::utf8($data); ?>

Apocalypse Meow:

{{error}}

{{error}}

 

 
1) { ?>


127.0.0.1,
127.0.0.0/24,
127.0.0.1-127.0.0.10




127.0.0.1,
127.0.0.0/24,
127.0.0.1-127.0.0.10

 

' . esc_html__('wp-config.php', 'apocalypse-meow') . '' ); ?>

' . esc_html__('You might also enjoy these other fine and practical plugins from %s.', 'apocalypse-meow'), 'Apocalypse Meow', 'Blobfolio, LLC' ); ?>

' . esc_html__('To Receive, Your Must Give.', 'apocalypse-meow') . ' ' . esc_html__('It is, after all, a community. Haha.', 'apocalypse-meow') ); // @codingStandardsIgnoreEnd echo '

' . implode('

', $out) . '

'; ?>

:

wp-config.php' ); ?>

Kitten Kitten

' . esc_html__('Information about your site is *never* shared with other Community Pool participants. The Meow API acts as a go-between.', 'apocalypse-meow') . '

'; echo '

' . esc_html__('But that said, this is not usually data that would be leaving your site, so if you are not comfortable with the idea, please leave this feature disabled!', 'apocalypse-meow') . '

'; ?>

admin', 'administrator' ), ); echo '

' . esc_html__('The following details from failed login attempts are shared:', 'apocalypse-meow') . '

  • ' . implode('
  • ', $out) . '
'; ?>

' . implode('

', $out) . '

'; // Output the table. $out = array( __('Domain', 'apocalypse-meow')=>common\sanitize::hostname(site_url()), __('OS', 'apocalypse-meow')=>PHP_OS, __('PHP', 'apocalypse-meow')=>PHP_VERSION, __('WordPress', 'apocalypse-meow')=>common\format::decode_entities(get_bloginfo('version')), __('This Plugin', 'apocalypse-meow')=>about::get_local('Version'), __('Premium', 'apocalypse-meow')=>options::is_pro() ? __('Yes', 'apocalypse-meow') : __('No', 'apocalypse-meow'), __('Locale', 'apocalypse-meow')=>get_locale(), __('Timezone', 'apocalypse-meow')=>about::get_timezone(), ); echo ''; foreach ($out as $k=>$v) { echo ''; } echo '
' . esc_html($k) . '' . esc_html($v) . '
'; ?>

wp-config.php

wp-config.php' ), sprintf( esc_html__('This code sample contains the corresponding PHP code for every setting as currently configured. It can be copied as-is to %s, or certain pieces can be removed or tweaked as needed. Any options that site administrators should be allowed to change through this page should first be removed.', 'apocalypse-meow'), 'wp-config.php' ), sprintf( esc_html__('Note: while PHP constants can be shoved pretty much anywhere, these must be loaded into memory before the %s hook is fired or Apocalypse Meow might not see them. %s is the safest bet.', 'apocalypse-meow'), '' . (MEOW_MUST_USE ? 'muplugins_loaded' : 'plugins_loaded') . '', 'wp-config.php' ) ); // @codingStandardsIgnoreEnd echo '

' . implode('

', $out) . '

'; ?>
Kitten