Monitors logins made by form submissions, XML-RPC requests and
auth cookies

If a login failure uses data matching a past failure, the plugin
slows down response times. The more failures, the longer the delay.
This limits attackers ability to effectively probe your site,
so they’ll give up and go find an easier target.

If an account seems breached, the “user” is immediately logged out
and forced to use WordPress’ password reset utility. This prevents
any damage from being done and verifies the user’s identity. But
if the user is coming in from an IP address they have used in the
past, an email is sent to the user making sure it was them logging in.
All without intervention by an administrator.

Can notify the administrator of attacks and breaches

Supports IPv6

Thoroughly examines and enforces password strength. Includes full
UTF-8 character set support if PHP’s mbstring extension is enabled.
The tests have caught every password dictionary entry I’ve tried.

Minimum length (customizable)

Doesn’t match blog info

Doesn’t match user data

Must either have numbers, punctuation, upper and lower case characters
or be very long. Note: alphabets with only one case (e.g. Arabic,
Hebrew, etc.) are automatically exempted from the upper/lower case
requirement.

Non-sequential codepoints

Non-sequential keystrokes (custom sequence files can be added)

Not in the password dictionary files you’ve provided (if any)

Decodes “leet” speak

The password/phrase is not found by the dict dictionary
program (if available)

Blocks discovering user names via the “?author=” query string

Password aging (optional) (not recommended)

Users need to change password every x days (customizable)

Grace period for picking a new password (customizable)

Remembers old passwords (quantity is customizable)

Administrators can require all users to change their passwords

Done via a flag in each user’s database entry

No mail is sent, keeping your server off of spam lists

Logs out idle sessions (optional) (idle time is customizable)

Maintenance mode (optional)

Publicly viewable content remains visible

Disables logins by all users, except administrators

Logs out existing sessions, except administrators

Disables posting of comments

Useful for maintenance or emergency reasons

This is separate from WordPress’ maintenance mode

Prevents information disclosures from failed logins

Improvements Over Similar WordPress Plugins

Multisite network support

Monitors authentication cookies for bad user names and hashes

Tracks logins from XML-RPC requests

Adjusts WordPress’ password policy user interfaces

Takes security seriously so the plugin itself does not open your site
to SQL, HTML, or header injection vulnerabilities

Notice-free code means no information disclosures if display_errors
is on and error_reporting includes E_NOTICE

Only loads files, actions, and filters needed for enabled options
and the page’s context

Provides an option to have deactivation remove all of this plugin’s
data from the database

Strong, Unique Passwords Are Important

Yeah, creating, storing/remembering, and using a different, strong
password for each site you use is a hassle. But it is absolutely
necessary.

Password lists get stolen on a regular basis from big name sites (like
Linkedin for example!). Criminals then have unlimited time to decode the
passwords. In general, 50% of those passwords are so weak they get figured
out in a matter of seconds. Plus there are computers on the Internet
dedicated to pounding the sites with login attempts, hoping to get lucky.

Many people use the same password for multiple sites. Once an attacker
figures out your password on one site, they’ll try it on your accounts at
other sites. It gets ugly very fast.

But don’t despair! There are good, free tools that make doing the right
thing a piece of cake. For example: KeePassX,KeePass,
or 1Password

Securing Your WordPress Site is Important

You’re probably thinking “There’s nothing valuable on my website. No one
will bother breaking into it.” What you need to realize is that attackers
are going after your visitors. They put stealth code on your website
that pushes malware into your readers’ browsers.

According to SophosLabs more than 30,000 websites are infected
every day and 80% of those infected sites are legitimate.
Eighty-five percent of all malware, including viruses, worms,
spyware, adware and Trojans, comes from the web. Today,
drive-by downloads have become the top web threat.

So if your site does get cracked, not only do you waste hours cleaning up,
your reputation gets sullied, security software flags your site as dangerous,
and worst of all, you’ve inadvertently helped infect the computers of your
clients and friends. Oh, and if the attack involves malware, that malware
has probably gotten itself into your computer.

Actions

login_security_solution_insert_fail

login_security_solution_notify_breach

login_security_solution_notify_fail

login_security_solution_fail_tier_dos

Filters

The following filters allow customizing email subjects and messages. If
either the “subject”or “message” filters in a method returns an empty
string, the given method will skip calling wp_mail().

login_security_solution_notify_breach_subject

login_security_solution_notify_breach_message

login_security_solution_notify_breach_user_subject

login_security_solution_notify_breach_user_message

login_security_solution_notify_fail_subject

login_security_solution_notify_fail_message

Unit Tests

A thorough set of unit tests are found in the tests directory.

The plugin needs to be installed and activated before running the tests.

To execute the tests, cd into this plugin’s directory and
call phpunit tests

Translations can be tested by changing the WPLANG value in wp-config.php.

Please note that the tests make extensive use of database transactions.
Many tests will be skipped if your wp_options and wp_usermeta tables
are not using the InnoDB storage engine.

Removal

This plugin offers the ability to remove all of this plugin’s settings
from your database. Go to WordPress’ “Plugins” admin interface and
click the “Settings” link for this plugin. In the “Deactivate” entry,
click the “Yes, delete the damn data” button and save the form.

Use WordPress’ “Plugins” admin interface to click the “Deactivate” link

Remove the login-security-solution directory from the server

In the event you didn’t pick the “Yes, delete the damn data” option or
you manually deleted the plugin, you can get rid of the settings by running
three queries. These queries are exapmles, using the default table name
prefix of, wp_. If you have changed your database prefix, adjust the
queries accordingly.

DROP TABLE wp_login_security_solution_fail;
DELETE FROM wp_options WHERE option_name LIKE 'login-security-solution%';
DELETE FROM wp_usermeta WHERE meta_key LIKE 'login-security-solution%';= Inspiration and References =

To Do

Provide a user interface to the fail table.

Before installing this plugin, read the FAQ!

If your WP install is behind a proxy or load balancer, please be aware
that this plugin uses the REMOTE_ADDR provided by the web server
(as does WordPress’ new comment functionality and the Akismet plugin).
If you want our brute force tracking to work, we advise adjusting your
wp-config.php file to manually set the REMOTE_ADDR to a data
source appropriate for your environment. For example:

Our existing tests are very effective, catching all of the 2 million
entries in the Dazzlepod password list. But if you need to block
specific passwords that my tests miss, this plugin offers the ability
to provide your own dictionary files.

Add a file to the pw_dictionaries directory and place those passwords
in it. One password per line.

Please be aware that checking the password files is computationally
expensive. The following script runs through each of the password
files and weeds out passwords caught by the other
tests:

php utilities/reduce-dictionary-files.php

If your website has a large number of non-English-speaking users:

See if a keyboard sequence file exists in this plugin’s
pw_sequences directory for your target languages. The following steps
are for left-to-right languages. (For right-to-left languages, flip the
direction of the motions indicated.)

Open a text editor and create a file in the pw_sequences
directory

Hold down the shift key

Press the top left character key of the keyboard.
NOTE: during this entire process, do not press function, control
or whitespace keys (like tab, enter, delete, arrows, space, etc).

Work your way across the top row, pressing each key across the
row, one by one

Press the left-most character key in the second row

Go across the second row pressing each key

Continue through the entire keyboard in the same manner

Let go of the shift key

Re-start the process at the top left key of the keyboard and
work your way through the keyboard, now in lower-case mode

Save the file and close the editor

Feel free to submit the files to me so others can use it. See
the features request section, below.

If a translation file for your language does not exist in this
plugin’s languages directory, add one. Read
https://codex.wordpress.org/I18n_for_WordPress_Developers for
details. The files must use UTF-8 encoding. Send me the file and
I’ll include it in future releases. See the features request
section, below.

The last step of the new password validation process is checking if
the password matches an entry in the dict program. See if dict
is installed on your server and consider installing it if not.
http://en.wikipedia.org/wiki/Dict

Adjust the settings as desired. This plugin’s settings page can be
reached via a sub-menu entry under WordPress’ “Settings” menu or this
plugin’s entry on WordPress’ “Plugins” page. Sites using WordPress’
multisite network capability will find the “Settings” and “Plugin”
menus under “My Sites | Network Admin”.

Run the “Change All Passwords” process. This is necessary to ensure
all of your users have strong passwords. The user interface for
doing so is accessible via a link in this plugin’s entry on
WordPress’ “Plugins” page.

Ensure your password strength by changing it.

Hooks

If your WP install is behind a proxy or load balancer, please be aware
that this plugin uses the REMOTE_ADDR provided by the web server
(as does WordPress’ new comment functionality and the Akismet plugin).
If you want our brute force tracking to work, we advise adjusting your
wp-config.php file to manually set the REMOTE_ADDR to a data
source appropriate for your environment. For example:

Our existing tests are very effective, catching all of the 2 million
entries in the Dazzlepod password list. But if you need to block
specific passwords that my tests miss, this plugin offers the ability
to provide your own dictionary files.

Add a file to the pw_dictionaries directory and place those passwords
in it. One password per line.

Please be aware that checking the password files is computationally
expensive. The following script runs through each of the password
files and weeds out passwords caught by the other
tests:

php utilities/reduce-dictionary-files.php

If your website has a large number of non-English-speaking users:

See if a keyboard sequence file exists in this plugin’s
pw_sequences directory for your target languages. The following steps
are for left-to-right languages. (For right-to-left languages, flip the
direction of the motions indicated.)

Open a text editor and create a file in the pw_sequences
directory

Hold down the shift key

Press the top left character key of the keyboard.
NOTE: during this entire process, do not press function, control
or whitespace keys (like tab, enter, delete, arrows, space, etc).

Work your way across the top row, pressing each key across the
row, one by one

Press the left-most character key in the second row

Go across the second row pressing each key

Continue through the entire keyboard in the same manner

Let go of the shift key

Re-start the process at the top left key of the keyboard and
work your way through the keyboard, now in lower-case mode

Save the file and close the editor

Feel free to submit the files to me so others can use it. See
the features request section, below.

If a translation file for your language does not exist in this
plugin’s languages directory, add one. Read
https://codex.wordpress.org/I18n_for_WordPress_Developers for
details. The files must use UTF-8 encoding. Send me the file and
I’ll include it in future releases. See the features request
section, below.

The last step of the new password validation process is checking if
the password matches an entry in the dict program. See if dict
is installed on your server and consider installing it if not.
http://en.wikipedia.org/wiki/Dict

Adjust the settings as desired. This plugin’s settings page can be
reached via a sub-menu entry under WordPress’ “Settings” menu or this
plugin’s entry on WordPress’ “Plugins” page. Sites using WordPress’
multisite network capability will find the “Settings” and “Plugin”
menus under “My Sites | Network Admin”.

Run the “Change All Passwords” process. This is necessary to ensure
all of your users have strong passwords. The user interface for
doing so is accessible via a link in this plugin’s entry on
WordPress’ “Plugins” page.

Ensure your password strength by changing it.

Hooks

Better WP Security: Their “Enable Login Limits” and “Enable strong
password enforcement” functionality conflict with our features. The good
news is we provide more robust protection in those areas and the Better WP
Security “Settings” page lets you disable those features in their plugin.
This way you get to enjoy even better security than either plugin alone.

Why should I pick a user name other than “admin”?

The WordPress installation process (currently) defaults to having the
main administrator’s user’s name be “admin.” Many people don’t change it.
Attackers know this, so now all they need to do to get into such sites is
guess the password.

In addition, if you try to log in while your site is being attacked, this
plugin will send you through the password reset process in order to verify
your identity. While not the end of the world, it’s inconvenient.

Where did the “Change All Passwords” interface go?

A link to the page is found in this plugin’s entry in the “Plugins” admin
interface:

Regular sites: Plugins

Sites using multisite networks: My Sites | Network Admin | Plugins

I just got hit with 500 failed logins! Why isn’t this plugin working?!?

Let’s turn the question around: “How long did it take to get in those 500
hits?” Chances are it took hours. (Six hours if they’re attacking with one
thread, 2 hours if they’re coming at you with three threads, etc.) If this
plugin wasn’t working, they’d have pulled it off under a minute. Similarly,
without the slowed responses this plugin provides, an attacker given six
hours against your site could probably get in over 170,000 hits.

Anyway, my real question for you is “Did they get in?” I’ll bet not. The
strong passwords this plugin requires from your users lowers the chances of
someone breaking in to just about zero.

And even if they do get lucky and figure out a password, Login Security
Solution realizes they’re miscreants and kicks them out.

Will you provide lock outs / blocks in addition to slow downs?

If you look at it the right way, Login Security Solution provides lockouts
(where “lockout” means “denies access” to attackers.) Below is a comparison
of the attack handling logic used by Limit Login Attempts and Login Security
Solution.

Limit Login Attempts

Invalid or Valid Credentials by Attacker or Actual User

Process authentication request (check IP address)

Error message: “Too many failed login attempts.” (ACCESS DENIED.)

Note, this approach means an actual user can be denied access for 12 hours after making 4 mistakes.

Login Security Solution

Invalid Credentials by Attacker or Actual User

Process authentication request (check IP, user name, and password)

Slow down the response

Error message: “Incorrect username or password.” (ACCESS DENIED.)

Valid Credentials by Attacker

Process authentication request (check IP, user name, and password)

Slow down the response

Set force password change flag for user

Error message: “Your password must be reset. Please submit this form to reset it.” (ACCESS DENIED.)

Valid Credentials by Actual User

Process authentication request (check IP, user name, and password)

(If user is coming from their verified IP address, let them in, END)

Slow down the response

Error message: “Your password must be reset. Please submit this form to reset it.” (ACCESS DENIED.)

User’s IP address is added to their verified IP list for future reference

So both plugins deny access to attackers. But Login Security Solution has
the bonuses of letting legitimate users log in and slowing the attacks down.
Plus LSS monitors user names, passwords, and IP’s for attacks, while all of
the other plugins just watch the IP address.

Won’t the slowdowns open my website to Denial of Service (DOS) attacks?

Yeah, the DOS potential is there. I mitigated it for the most part by
disconnecting the database link (the most precious resource in most
situations) before sleeping. But remember, distributed denial of service
attacks are fairly easy to initiate these days. If someone really wants to
shut down your site, they’ll be able to do it without even touching this
plugin’s login failure process.

Do not commit the .mo files! They get created as part of the
release process.

Translation commits and pull requests should only touch the .po
file. If you have other changes you wish to see made, please do so
via separate commits in separate pull requests.

When translating a new feature, please make that one commit. If other
parts of the translation need updating, please make them in a separate
commit.

Please don’t change formatting inside the .po file

Run git diff before all commits. Ensure only expected changes
are being made.

Do NOT translate items that have a comment above them saying
Translation from WordPress. DO NOT TRANSLATE IT IN THIS PLUGIN.
When starting a new translation, please take a look at an existing
.po file to see which strings they are. Those phrases are already
translated in WordPress’ core. Leaving them untranslated here ensures
consistency with the rest of WordPress.

To start a new translation:

cd languages

Adjust “CC” to your country code.

cp login-security-solution.pot login-security-solution-lc_CC.po

Edit the new login-security-solution-lc_CC.po file.

Translation Information for Developers

To update the .pot file:

WordPress’ makepot utility directory should be in the same directory
as the login-security-solution directory. If you don’t have this
setup, here’s what to do:

cd into the directory above this one.

svn checkout https://i18n.svn.wordpress.org/tools/trunk/ makepot

So, now you’ll have:

parent dir
|- login-security-solution/
|- makepot/

cd login-security-solution/languages

./makepot.sh

Then, bringing the .po files up to date is as easy as:

./updatepos.sh

Finally, to update the .mo files for testing or release:

./makemos.sh

0.56.0 (2016-08-13)

Fix translation domain to be string in one __() call.

0.55.0 (2016-01-30)

Block discovering user names via the “?author=” query string

0.54.0 (2016-01-27)

Fix memory exhaustion on sites with many users during plugin activation
if password history is enabled

Put “in” in “Please log and change it”

0.53.0 (2015-09-25)

Change translation domain from constant to string in preparation for
integration with translate.wordpress.org

0.52.0 (2015-05-25)

Silence safe mode warnings from is_readable()

Add Polish translation

Add Finnish translation

Rename Japanese translation files from ja_JP to ja

0.51.0 (2015-03-15)

Security Fixes:

Remove calls to dict. Parse dict file if available instead.

Remove use of grep.

0.50.0 (2014-12-25)

Take advantage of WP 4.1’s new password_hint filter

Add Italian translation

0.49.0 (2014-11-10)

Fix password policy hint on password reset form broken by changes in WP

Developed for private use, but has perspective for more extensive usage. I can’t guarantee any support in the future nor further development, but it is to be expected. Kindly inform me about bugs, if you find any, or propose new features: zaantar@zaantar.eu.

The Long Version

In the future (PHP 7.2) we may have an option for Argon2 hashing, to eventually replace Bcrypt.

The plugin gracefully replaces WordPress password hashing (MD5) with PHP 5.5+ built in hashing which is much stronger, so in the case your password hashes are exposed it would be much more difficult for hackers to brute force them.

Compatibility

This plugin has been designed for use on LEMP (Nginx) web servers with PHP 7.0 and MySQL 5.7 to achieve best performance. All of our plugins are meant for single site WordPress installations only; for both performance and security reasons, we highly recommend against using WordPress Multisite for the vast majority of projects.

WP Admin Notices

This plugin generates multiple Admin Notices in the WP Admin dashboard. The first is a notice that fires during plugin activation which recommends several related free plugins that we believe will enhance this plugin’s features; this notice will re-appear approximately once every 6 months as our code and recommendations evolve. The second is a notice that fires a few days after plugin activation which asks for a 5-star rating of this plugin on its WordPress.org profile page. This notice will re-appear approximately once every 9 months. These notices can be dismissed by clicking the (x) symbol in the upper right of the notice box. These notices may annoy or confuse certain users, but are appreciated by the majority of our userbase, who understand that these notices support our free contributions to the WordPress community while providing valuable (free) recommendations for optimizing their website.

If you feel that these notices are too annoying, than we encourage you to consider one or more of our upcoming premium plugins that combine several free plugin features into a single control panel, or even consider developing your own plugins for WordPress, if supporting free plugin authors is too frustrating for you. A final alternative would be to place the defined constant mentioned below inside of your wp-config.php file to manually hide this plugin’s nag notices:

define('DISABLE_NAG_NOTICES', true);

Note: This defined constant will only affect the notices mentioned above, and will not affect any other notices generated by this plugin or other plugins, such as one-time notices that communicate with admin-level users.

Code Inspiration

This plugin was partially inspired either in “code or concept” by the open-source software and discussions mentioned below:

Disclaimer

We released this plugin in response to our managed hosting clients asking for better access to their server, and our primary goal will remain supporting that purpose. Although we are 100% open to fielding requests from the WordPress community, we kindly ask that you keep the above mentioned goals in mind, thanks!

Upload to /wp-content/plugins/force-strong-hashing-littlebizzy

Activate via WP Admin > Plugins

Test plugin is working by viewing new complex password hashes stored in your database

Installation Instructions

Upload to /wp-content/plugins/force-strong-hashing-littlebizzy

Activate via WP Admin > Plugins

Test plugin is working by viewing new complex password hashes stored in your database

How can I change this plugin’s settings?

There is no settings page for optimal performance and simplicity.

I have a suggestion, how can I let you know?

Please avoid leaving negative reviews in order to get a feature implemented. Instead, we kindly ask that you post your feedback on the wordpress.org support forums by tagging this plugin in your post. If needed, you may also contact our homepage.

1.0.4

tested with WP 4.9

added support for define('DISABLE_NAG_NOTICES', true);

1.0.3

optimized plugin code

updated recommended plugins

added rating request

1.0.2

updated recommended plugins

1.0.1

added recommended plugins

1.0.0

This plugin will : In the visual editor and text editor, when you click the B button, change the output tag from ‘strong’ to ‘b’ .
And when you click the I button, change the output tag from ’em’ tag to ‘i’ tag.

Additionally, the b and i elements were deprecated in HTML 4.01 and XHTML. This plugin corrects these deprecated tags without modifying your data. (If you uninstall the plugin, your blog works as if this plugin was never installed.)

Unzip the zip file into the /wp-content/plugins/ directory. Activate the plugin through the ‘Plugins’ menu in WordPress.

Can I still use SyntaxHighlighter to post source code with ‘b’ and ‘i’ elements?

Yes. I have tested this plugin, and it is compatible with the SyntaxHighlighter Evolved plugin. If you install the SyntaxHighlighter plugin and you are purposely trying to post HTML code snippets, for example, then b and i tags will not be converted into strong and em tags.