{"id":900,"date":"2012-03-21T19:07:57","date_gmt":"2012-03-21T19:07:57","guid":{"rendered":"https:\/\/wordpress.org\/plugins-wp\/login-security-solution\/"},"modified":"2016-08-13T17:19:46","modified_gmt":"2016-08-13T17:19:46","slug":"login-security-solution","status":"publish","type":"plugin","link":"https:\/\/da.wordpress.org\/plugins\/login-security-solution\/","author":8850706,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","version":"0.56.0","stable_tag":"trunk","tested":"4.4.34","requires":"3.3","requires_php":"","requires_plugins":"","header_name":"Login Security Solution","header_author":"Daniel Convissor","header_description":"","assets_banners_color":"","last_updated":"2017-11-28 10:46:26","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/www.paypal.com\/cgi-bin\/webscr?cmd=_donations&business=danielc%40analysisandsolutions%2ecom&lc=US&item_name=Donate%3a%20Login%20Security%20Solution&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted","header_plugin_uri":"https:\/\/wordpress.org\/plugins\/login-security-solution\/","header_author_uri":"http:\/\/www.analysisandsolutions.com\/","rating":4.4,"author_block_rating":0,"active_installs":4000,"downloads":290399,"num_ratings":54,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":[],"upgrade_notice":[],"ratings":{"1":3,"2":5,"3":1,"4":5,"5":40},"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.0.4","0.1.0","0.10.0","0.11.0","0.12.0","0.13.0","0.14.0","0.15.0","0.16.0","0.17.0","0.18.0","0.19.0","0.2.1","0.20.0","0.20.1","0.20.2","0.21.0","0.22.0","0.23.0","0.24.0","0.25.0","0.26.0","0.27.0","0.28.0","0.28.1","0.29.0","0.3.0","0.30.0","0.4.0","0.5.0","0.6.0","0.6.1","0.7.0","0.8.0","0.9.0"],"block_files":[],"assets_screenshots":[],"screenshots":[],"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[602,1930,8588,8589,8590],"plugin_category":[38,52,54],"plugin_contributors":[78723],"plugin_business_model":[],"class_list":["post-900","plugin","type-plugin","status-publish","hentry","plugin_tags-login","plugin_tags-password","plugin_tags-passwords","plugin_tags-strength","plugin_tags-strong","plugin_category-authentication","plugin_category-performance","plugin_category-security-and-spam-protection","plugin_contributors-convissor","plugin_committers-convissor"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/login-security-solution.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p>A simple way to lock down login security for multisite and regular\nWordPress installations.<\/p>\n\n<ul>\n<li><p>Blocks brute force and dictionary attacks without inconveniencing\nlegitimate users or administrators<\/p>\n\n<ul>\n<li>Tracks IP addresses, usernames, and passwords<\/li>\n<li>Monitors logins made by form submissions, XML-RPC requests and\nauth cookies<\/li>\n<li>If a login failure uses data matching a past failure, the plugin\nslows down response times.  The more failures, the longer the delay.\nThis limits attackers ability to effectively probe your site,\nso they'll give up and go find an easier target.<\/li>\n<li>If an account seems breached, the \"user\" is immediately logged out\nand forced to use WordPress' password reset utility.  This prevents\nany damage from being done and verifies the user's identity.  But\nif the user is coming in from an IP address they have used in the\npast, an email is sent to the user making sure it was them logging in.\nAll without intervention by an administrator.<\/li>\n<li>Can notify the administrator of attacks and breaches<\/li>\n<li>Supports IPv6<\/li>\n<\/ul><\/li>\n<li><p>Thoroughly examines and enforces password strength.  Includes full\nUTF-8 character set support if PHP's <code>mbstring<\/code> extension is enabled.\nThe tests have caught every password dictionary entry I've tried.<\/p>\n\n<ul>\n<li>Minimum length (customizable)<\/li>\n<li>Doesn't match blog info<\/li>\n<li>Doesn't match user data<\/li>\n<li>Must either have numbers, punctuation, upper and lower case characters\nor be very long.  Note: alphabets with only one case (e.g. Arabic,\nHebrew, etc.) are automatically exempted from the upper\/lower case\nrequirement.<\/li>\n<li>Non-sequential codepoints<\/li>\n<li>Non-sequential keystrokes (custom sequence files can be added)<\/li>\n<li>Not in the password dictionary files you've provided (if any)<\/li>\n<li>Decodes \"leet\" speak<\/li>\n<li>The password\/phrase is not found by the <code>dict<\/code> dictionary\nprogram (if available)<\/li>\n<\/ul><\/li>\n<li><p>Blocks discovering user names via the \"?author=\" query string<\/p><\/li>\n<li><p>Password aging (optional) (not recommended)<\/p>\n\n<ul>\n<li>Users need to change password every x days (customizable)<\/li>\n<li>Grace period for picking a new password (customizable)<\/li>\n<li>Remembers old passwords (quantity is customizable)<\/li>\n<\/ul><\/li>\n<li><p>Administrators can require all users to change their passwords<\/p>\n\n<ul>\n<li>Done via a flag in each user's database entry<\/li>\n<li>No mail is sent, keeping your server off of spam lists<\/li>\n<\/ul><\/li>\n<li><p>Logs out idle sessions (optional) (idle time is customizable)<\/p><\/li>\n<li><p>Maintenance mode (optional)<\/p>\n\n<ul>\n<li>Publicly viewable content remains visible<\/li>\n<li>Disables logins by all users, except administrators<\/li>\n<li>Logs out existing sessions, except administrators<\/li>\n<li>Disables posting of comments<\/li>\n<li>Useful for maintenance or emergency reasons<\/li>\n<li>This is separate from WordPress' maintenance mode<\/li>\n<\/ul><\/li>\n<li><p>Prevents information disclosures from failed logins<\/p><\/li>\n<\/ul>\n\n<h4>Improvements Over Similar WordPress Plugins<\/h4>\n\n<ul>\n<li>Multisite network support<\/li>\n<li>Monitors authentication cookies for bad user names and hashes<\/li>\n<li>Tracks logins from XML-RPC requests<\/li>\n<li>Adjusts WordPress' password policy user interfaces<\/li>\n<li>Takes security seriously so the plugin itself does not open your site\nto SQL, HTML, or header injection vulnerabilities<\/li>\n<li>Notice-free code means no information disclosures if <code>display_errors<\/code>\nis on and <code>error_reporting<\/code> includes <code>E_NOTICE<\/code><\/li>\n<li>Only loads files, actions, and filters needed for enabled options\nand the page's context<\/li>\n<li>Provides an option to have deactivation remove all of this plugin's\ndata from the database<\/li>\n<li>Uses WordPress' features rather than fighting or overriding them<\/li>\n<li>No advertising, promotions, or beacons<\/li>\n<li>Proper internationalization support<\/li>\n<li>Clean, documented code<\/li>\n<li>Unit tests covering 100% of the main class<\/li>\n<li>Internationalized unit tests<\/li>\n<\/ul>\n\n<p>For reference, the similar plugins include:<\/p>\n\n<ul>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/6scan-protection\/\">6Scan Security<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/better-wp-security\/\">Better WP Security<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/enforce-strong-password\/\">Enforce Strong Password<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/force-strong-passwords\/\">Force Strong Passwords<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/limit-login-attempts\/\">Limit Login Attempts<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/login-lock\/\">Login Lock<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/login-lockdown\/\">Login LockDown<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/pmc-lockdown\/\">PMC Lockdown<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/simple-login-lockdown\/\">Simple Login Lockdown<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/wordfence\/\">Wordfence Security<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/wp-login-security\/\">WP Login Security<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/wp-login-security-2\/\">WP Login Security 2<\/a><\/li>\n<\/ul>\n\n<h4>Compatibility with Other Plugins<\/h4>\n\n<p>Some plugins provide similar functionality.  These overlaps can lead to\nconflicts during program execution.  Please read the FAQ!<\/p>\n\n<h4>Translations<\/h4>\n\n<ul>\n<li>Deutsche, Deutschland (German, Germany) (de_DE) by Christian Foellmann<\/li>\n<li>Fran\u00e7ais, fran\u00e7ais (French, France) (fr_FR) by <a href=\"https:\/\/profiles.wordpress.org\/mermouy\">mermouy<\/a> and and Fx B\u00e9nard<\/li>\n<li>Italiano, Italia (Italian, Italy) (it_IT) by Daniele Passalacqua<\/li>\n<li>\u65e5\u672c\u8a9e, \u65e5\u672c\u56fd (Japanese, Japan) (ja_JP) by <a href=\"https:\/\/profiles.wordpress.org\/motoyamayuki\/\">motoyamayuki<\/a><\/li>\n<li>Nederlands, Nederland (Dutch, Netherlands) (nl_NL) by Friso van Wieringen<\/li>\n<li>polski, Polska (Polish, Poland) (pl_PL) by Micha\u0142 Seweryniak <a href=\"https:\/\/github.com\/miniol\">miniol<\/a><\/li>\n<li>Portugu\u00eas, Brasil (Portugese, Brazil) (pt_BR) by Valdir Trombini<\/li>\n<li>suomi, Suomi (Finnish, Finland) (fi_FI) by Juha Remes <a href=\"https:\/\/github.com\/Newman101\">Newman101<\/a><\/li>\n<\/ul>\n\n<h4>Source Code, Bugs, and Feature Requests<\/h4>\n\n<p>Development of this plugin happens on\n<a href=\"https:\/\/github.com\/convissor\/login-security-solution\">GitHub<\/a>.\nPlease submit\n<a href=\"https:\/\/github.com\/convissor\/login-security-solution\/issues\">bug and feature requests<\/a>,\n<a href=\"https:\/\/github.com\/convissor\/login-security-solution\/pulls\">pull requests<\/a>,\n<a href=\"https:\/\/github.com\/convissor\/login-security-solution\/wiki\">wiki entries<\/a>\nthere.\nReleases are then squashed and pushed to WordPress'\n<a href=\"http:\/\/plugins.svn.wordpress.org\/login-security-solution\/\">Plugins SVN repository<\/a>.\nThis division is necessary due having being chastised that \"the Plugins SVN\nrepository is a release system, not a development system.\"<\/p>\n\n<p>Old tickets are in the <a href=\"https:\/\/plugins.trac.wordpress.org\/query?status=assigned&amp;status=closed&amp;status=new&amp;status=reopened&amp;component=login-security-solution&amp;col=id&amp;col=summary&amp;col=status&amp;col=owner&amp;col=type&amp;col=priority&amp;col=component&amp;desc=1&amp;order=id\">Plugins Trac<\/a>.<\/p>\n\n<h4>Strong, Unique Passwords Are Important<\/h4>\n\n<p>Yeah, creating, storing\/remembering, and using a <strong>different<\/strong>, <strong>strong<\/strong>\npassword for each site you use is a hassle.  <em>But it is absolutely\nnecessary.<\/em><\/p>\n\n<p>Password lists get stolen on a regular basis from big name sites (like\nLinkedin for example!).  Criminals then have unlimited time to decode the\npasswords.  In general, 50% of those passwords are so weak they get figured\nout in a matter of seconds.  Plus there are computers on the Internet\ndedicated to pounding the sites with login attempts, hoping to get lucky.<\/p>\n\n<p>Many people use the same password for multiple sites.  Once an attacker\nfigures out your password on one site, they'll try it on your accounts at\nother sites.  It gets ugly very fast.<\/p>\n\n<p>But don't despair!  There are good, free tools that make doing the right\nthing a piece of cake.  For example: <a href=\"http:\/\/www.keepassx.org\/\">KeePassX<\/a>,\n<a href=\"http:\/\/keepass.info\/\">KeePass<\/a>,\nor <a href=\"https:\/\/agilebits.com\/onepassword\">1Password<\/a><\/p>\n\n<h4>Securing Your WordPress Site is Important<\/h4>\n\n<p>You're probably thinking \"There's nothing valuable on my website. No one\nwill bother breaking into it.\"  What you need to realize is that attackers\nare going after your visitors.  They put stealth code on your website\nthat pushes malware into your readers' browsers.<\/p>\n\n<blockquote>\n  <p>According to SophosLabs more than 30,000 websites are infected\n  every day and 80% of those infected sites are legitimate.\n  Eighty-five percent of all malware, including viruses, worms,\n  spyware, adware and Trojans, comes from the web. Today,\n  drive-by downloads have become the top web threat.<\/p>\n  \n  <p>-- <a href=\"http:\/\/www.sophos.com\/en-us\/security-news-trends\/reports\/security-threat-report\/html-08.aspx\"><em>Security Threat Report 2012<\/em><\/a><\/p>\n<\/blockquote>\n\n<p>So if your site does get cracked, not only do you waste hours cleaning up,\nyour reputation gets sullied, security software flags your site as dangerous,\nand worst of all, you've inadvertently helped infect the computers of your\nclients and friends.  Oh, and if the attack involves malware, that malware\nhas probably gotten itself into your computer.<\/p>\n\n<h3>Actions<\/h3>\n\n<ul>\n<li>login_security_solution_insert_fail<\/li>\n<li>login_security_solution_notify_breach<\/li>\n<li>login_security_solution_notify_fail<\/li>\n<li>login_security_solution_fail_tier_dos<\/li>\n<\/ul>\n\n<h3>Filters<\/h3>\n\n<p>The following filters allow customizing email subjects and messages.  If\neither the \"subject\"or \"message\" filters in a method returns an empty\nstring, the given method will skip calling <code>wp_mail()<\/code>.<\/p>\n\n<ul>\n<li>login_security_solution_notify_breach_subject<\/li>\n<li>login_security_solution_notify_breach_message<\/li>\n<li>login_security_solution_notify_breach_user_subject<\/li>\n<li>login_security_solution_notify_breach_user_message<\/li>\n<li>login_security_solution_notify_fail_subject<\/li>\n<li>login_security_solution_notify_fail_message<\/li>\n<\/ul>\n\n<h4>Unit Tests<\/h4>\n\n<p>A thorough set of unit tests are found in the <code>tests<\/code> directory.<\/p>\n\n<p>The plugin needs to be installed and activated before running the tests.<\/p>\n\n<p>To execute the tests, <code>cd<\/code> into this plugin's directory and\ncall <code>phpunit tests<\/code><\/p>\n\n<p>Translations can be tested by changing the <code>WPLANG<\/code> value in <code>wp-config.php<\/code>.<\/p>\n\n<p>Please note that the tests make extensive use of database transactions.\nMany tests will be skipped if your <code>wp_options<\/code> and <code>wp_usermeta<\/code> tables\nare not using the <code>InnoDB<\/code> storage engine.<\/p>\n\n<h4>Removal<\/h4>\n\n<ol>\n<li><p>This plugin offers the ability to remove all of this plugin's settings\nfrom your database.  Go to WordPress' \"Plugins\" admin interface and\nclick the \"Settings\" link for this plugin.  In the \"Deactivate\" entry,\nclick the \"Yes, delete the damn data\" button and save the form.<\/p><\/li>\n<li><p>Use WordPress' \"Plugins\" admin interface to click the \"Deactivate\" link<\/p><\/li>\n<li><p>Remove the <code>login-security-solution<\/code> directory from the server<\/p><\/li>\n<\/ol>\n\n<p>In the event you didn't pick the \"Yes, delete the damn data\" option or\nyou manually deleted the plugin, you can get rid of the settings by running\nthree queries.  These  queries are exapmles, using the default table name\nprefix of, <code>wp_<\/code>.  If you have changed your database prefix, adjust the\nqueries accordingly.<\/p>\n\n<pre><code>    DROP TABLE wp_login_security_solution_fail;\n\n    DELETE FROM wp_options WHERE option_name LIKE 'login-security-solution%';\n\n    DELETE FROM wp_usermeta WHERE meta_key LIKE 'login-security-solution%';= Inspiration and References =\n<\/code><\/pre>\n\n<ul>\n<li><p>Password Research<\/p>\n\n<ul>\n<li><a href=\"http:\/\/arstechnica.com\/security\/2012\/08\/passwords-under-assault\/\">Why passwords have never been weaker -- and crackers have never been stronger<\/a>, Dan Goodin<\/li>\n<li><a href=\"http:\/\/www.cl.cam.ac.uk\/~jcb82\/doc\/B12-IEEESP-evaluating_a_huge_password_corpus.pdf\">You can never have too many passwords: techniques for evaluating a huge corpus<\/a>, Joseph Bonneau<\/li>\n<li><a href=\"http:\/\/www.cs.ru.nl\/bachelorscripties\/2010\/Martin_Devillers___0437999___Analyzing_password_strength.pdf\">Analyzing Password Strength<\/a>, Martin Devillers<\/li>\n<li><a href=\"http:\/\/www.imperva.com\/docs\/WP_Consumer_Password_Worst_Practices.pdf\">Consumer Password Worst Practices<\/a>, Imperva<\/li>\n<li><a href=\"http:\/\/www.bryanrite.com\/preventing-brute-force-attacks-on-your-web-login\/\">Preventing Brute Force Attacks on your Web Login<\/a>, Bryan Rite<\/li>\n<li><a href=\"http:\/\/xkcd.com\/936\/\">Password Strength<\/a>, Randall Munroe<\/li>\n<\/ul><\/li>\n<li><p>Technical Info<\/p>\n\n<ul>\n<li><a href=\"http:\/\/doc.infosnel.nl\/extreme_utf-8.html\">The Extreme UTF-8 Table<\/a>, infosnel.nl<\/li>\n<li><a href=\"http:\/\/tools.ietf.org\/html\/rfc5952\">A Recommendation for IPv6 Address Text Representation<\/a>, Seiichi Kawamura and Masanobu Kawashima<\/li>\n<\/ul><\/li>\n<li><p>Password Lists<\/p>\n\n<ul>\n<li><a href=\"http:\/\/dazzlepod.com\/site_media\/txt\/passwords.txt\">Dazzlepod Password List<\/a>, Dazzlepod<\/li>\n<li><a href=\"http:\/\/www.searchlores.org\/commonpass1.htm\">Common Passwords<\/a>, Fravia<\/li>\n<li><a href=\"http:\/\/www.whatsmypass.com\/the-top-500-worst-passwords-of-all-time\">The Top 500 Worst Passwords of All Time<\/a>, Mark Burnett<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>To Do<\/h4>\n\n<ul>\n<li>Provide a user interface to the <code>fail<\/code> table.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li><p>Before installing this plugin, read the FAQ!<\/p><\/li>\n<li><p>If your WP install is behind a proxy or load balancer, please be aware\nthat this plugin uses the <code>REMOTE_ADDR<\/code> provided by the web server\n(as does WordPress' new comment functionality and the Akismet plugin).\nIf you want our brute force tracking to work, we advise adjusting your\n    wp-config.php file to manually set the <code>REMOTE_ADDR<\/code> to a data\nsource appropriate for your environment.  For example:<\/p>\n\n<pre><code>    $_SERVER['REMOTE_ADDR'] = preg_replace('\/^([^,]+).*$\/', '\\1',\n        $_SERVER['HTTP_X_FORWARDED_FOR']);\n<\/code><\/pre><\/li>\n<li><p>Download the Login Security Solution zip file from WordPress' plugin\nsite: <code>https:\/\/wordpress.org\/plugins\/login-security-solution\/<\/code><\/p><\/li>\n<li><p>Unzip the file.<\/p><\/li>\n<li><p>Our existing tests are very effective, catching all of the 2 million\nentries in the Dazzlepod password list.  But if you need to block\nspecific passwords that my tests miss, this plugin offers the ability\nto provide your own dictionary files.<\/p>\n\n<p>Add a file to the <code>pw_dictionaries<\/code> directory and place those passwords\nin it.  One password per line.<\/p>\n\n<p>Please be aware that checking the password files is computationally\nexpensive.  The following script runs through each of the password\nfiles and weeds out passwords caught by the other\ntests:<\/p>\n\n<pre><code>    php utilities\/reduce-dictionary-files.php\n<\/code><\/pre><\/li>\n<li><p>If your website has a large number of non-English-speaking users:<\/p>\n\n<ul>\n<li><p>See if a keyboard sequence file exists in this plugin's\npw_sequences directory for your target languages.  The following steps\nare for left-to-right languages.  (For right-to-left languages, flip the\ndirection of the motions indicated.)<\/p>\n\n<ul>\n<li>Open a text editor and create a file in the <code>pw_sequences<\/code>\ndirectory<\/li>\n<li>Hold down the shift key<\/li>\n<li>Press the top left <strong>character<\/strong> key of the keyboard.\nNOTE: during this entire process, do not press function, control\nor whitespace keys (like tab, enter, delete, arrows, space, etc).<\/li>\n<li>Work your way across the top row, pressing each key across the\nrow, one by one<\/li>\n<li>Press the left-most character key in the second row<\/li>\n<li>Go across the second row pressing each key<\/li>\n<li>Continue through the entire keyboard in the same manner<\/li>\n<li>Let go of the shift key<\/li>\n<li>Re-start the process at the top left key of the keyboard and\nwork your way through the keyboard, now in lower-case mode<\/li>\n<li>Save the file and close the editor<\/li>\n<li>Feel free to submit the files to me so others can use it.  See\nthe features request section, below.<\/li>\n<\/ul><\/li>\n<li><p>If a translation file for your language does not exist in this\nplugin's <code>languages<\/code> directory, add one.  Read\nhttp:\/\/codex.wordpress.org\/I18n_for_WordPress_Developers for\ndetails.  The files must use UTF-8 encoding.  Send me the file and\nI'll include it in future releases.  See the features request\nsection, below.<\/p><\/li>\n<\/ul><\/li>\n<li><p>The last step of the new password validation process is checking if\nthe password matches an entry in the <code>dict<\/code> program.  See if <code>dict<\/code>\nis installed on your server and consider installing it if not.\nhttp:\/\/en.wikipedia.org\/wiki\/Dict<\/p><\/li>\n<li><p>Upload the <code>login-security-solution<\/code> directory to your\nserver's <code>\/wp-content\/plugins\/<\/code> directory<\/p><\/li>\n<li><p>Activate the plugin using WordPress' admin interface:<\/p>\n\n<ul>\n<li>Regular sites:  Plugins<\/li>\n<li>Sites using multisite networks:  My Sites | Network Admin | Plugins<\/li>\n<\/ul><\/li>\n<li><p>Adjust the settings as desired.  This plugin's settings page can be\nreached via a sub-menu entry under WordPress' \"Settings\" menu or this\nplugin's entry on WordPress' \"Plugins\" page.  Sites using WordPress'\nmultisite network capability will find the \"Settings\" and \"Plugin\"\nmenus under \"My Sites | Network Admin\".<\/p><\/li>\n<li><p>Run the \"Change All Passwords\" process. This is necessary to ensure\nall of your users have strong passwords.  The user interface for\ndoing so is accessible via a link in this plugin's entry on\nWordPress' \"Plugins\" page.<\/p><\/li>\n<li><p>Ensure your password strength by changing it.<\/p><\/li>\n<\/ol>\n\n<h4>Hooks<\/h4>\n\n<p>Login Security Solution provides <a href=\"https:\/\/codex.wordpress.org\/Plugin_API\">hooks<\/a>\nin critical methods, allowing you to add custom behaviors.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt>Installation Instructions<\/dt>\n<dd><ol>\n<li><p>Before installing this plugin, read the FAQ!<\/p><\/li>\n<li><p>If your WP install is behind a proxy or load balancer, please be aware\nthat this plugin uses the <code>REMOTE_ADDR<\/code> provided by the web server\n(as does WordPress' new comment functionality and the Akismet plugin).\nIf you want our brute force tracking to work, we advise adjusting your\n    wp-config.php file to manually set the <code>REMOTE_ADDR<\/code> to a data\nsource appropriate for your environment.  For example:<\/p>\n\n<pre><code>    $_SERVER['REMOTE_ADDR'] = preg_replace('\/^([^,]+).*$\/', '\\1',\n        $_SERVER['HTTP_X_FORWARDED_FOR']);\n<\/code><\/pre><\/li>\n<li><p>Download the Login Security Solution zip file from WordPress' plugin\nsite: <code>https:\/\/wordpress.org\/plugins\/login-security-solution\/<\/code><\/p><\/li>\n<li><p>Unzip the file.<\/p><\/li>\n<li><p>Our existing tests are very effective, catching all of the 2 million\nentries in the Dazzlepod password list.  But if you need to block\nspecific passwords that my tests miss, this plugin offers the ability\nto provide your own dictionary files.<\/p>\n\n<p>Add a file to the <code>pw_dictionaries<\/code> directory and place those passwords\nin it.  One password per line.<\/p>\n\n<p>Please be aware that checking the password files is computationally\nexpensive.  The following script runs through each of the password\nfiles and weeds out passwords caught by the other\ntests:<\/p>\n\n<pre><code>    php utilities\/reduce-dictionary-files.php\n<\/code><\/pre><\/li>\n<li><p>If your website has a large number of non-English-speaking users:<\/p>\n\n<ul>\n<li><p>See if a keyboard sequence file exists in this plugin's\npw_sequences directory for your target languages.  The following steps\nare for left-to-right languages.  (For right-to-left languages, flip the\ndirection of the motions indicated.)<\/p>\n\n<ul>\n<li>Open a text editor and create a file in the <code>pw_sequences<\/code>\ndirectory<\/li>\n<li>Hold down the shift key<\/li>\n<li>Press the top left <strong>character<\/strong> key of the keyboard.\nNOTE: during this entire process, do not press function, control\nor whitespace keys (like tab, enter, delete, arrows, space, etc).<\/li>\n<li>Work your way across the top row, pressing each key across the\nrow, one by one<\/li>\n<li>Press the left-most character key in the second row<\/li>\n<li>Go across the second row pressing each key<\/li>\n<li>Continue through the entire keyboard in the same manner<\/li>\n<li>Let go of the shift key<\/li>\n<li>Re-start the process at the top left key of the keyboard and\nwork your way through the keyboard, now in lower-case mode<\/li>\n<li>Save the file and close the editor<\/li>\n<li>Feel free to submit the files to me so others can use it.  See\nthe features request section, below.<\/li>\n<\/ul><\/li>\n<li><p>If a translation file for your language does not exist in this\nplugin's <code>languages<\/code> directory, add one.  Read\nhttp:\/\/codex.wordpress.org\/I18n_for_WordPress_Developers for\ndetails.  The files must use UTF-8 encoding.  Send me the file and\nI'll include it in future releases.  See the features request\nsection, below.<\/p><\/li>\n<\/ul><\/li>\n<li><p>The last step of the new password validation process is checking if\nthe password matches an entry in the <code>dict<\/code> program.  See if <code>dict<\/code>\nis installed on your server and consider installing it if not.\nhttp:\/\/en.wikipedia.org\/wiki\/Dict<\/p><\/li>\n<li><p>Upload the <code>login-security-solution<\/code> directory to your\nserver's <code>\/wp-content\/plugins\/<\/code> directory<\/p><\/li>\n<li><p>Activate the plugin using WordPress' admin interface:<\/p>\n\n<ul>\n<li>Regular sites:  Plugins<\/li>\n<li>Sites using multisite networks:  My Sites | Network Admin | Plugins<\/li>\n<\/ul><\/li>\n<li><p>Adjust the settings as desired.  This plugin's settings page can be\nreached via a sub-menu entry under WordPress' \"Settings\" menu or this\nplugin's entry on WordPress' \"Plugins\" page.  Sites using WordPress'\nmultisite network capability will find the \"Settings\" and \"Plugin\"\nmenus under \"My Sites | Network Admin\".<\/p><\/li>\n<li><p>Run the \"Change All Passwords\" process. This is necessary to ensure\nall of your users have strong passwords.  The user interface for\ndoing so is accessible via a link in this plugin's entry on\nWordPress' \"Plugins\" page.<\/p><\/li>\n<li><p>Ensure your password strength by changing it.<\/p><\/li>\n<\/ol>\n\n<h4>Hooks<\/h4>\n\n<p>Login Security Solution provides <a href=\"https:\/\/codex.wordpress.org\/Plugin_API\">hooks<\/a>\nin critical methods, allowing you to add custom behaviors.<\/p><\/dd>\n<dt>Compatibility with Other Plugins<\/dt>\n<dd><ul>\n<li><strong>Better WP Security<\/strong>:  Their \"Enable Login Limits\" and \"Enable strong\npassword enforcement\" functionality conflict with our features.  The good\nnews is we provide more robust protection in those areas and the Better WP\nSecurity \"Settings\" page lets you disable those features in their plugin.\nThis way you get to enjoy even better security than either plugin alone.<\/li>\n<\/ul><\/dd>\n<dt>Why should I pick a user name other than \"admin\"?<\/dt>\n<dd><p>The WordPress installation process (currently) defaults to having the\nmain administrator's user's name be \"admin.\"  Many people don't change it.\nAttackers know this, so now all they need to do to get into such sites is\nguess the password.<\/p>\n\n<p>In addition, if you try to log in while your site is being attacked, this\nplugin will send you through the password reset process in order to verify\nyour identity.  While not the end of the world, it's inconvenient.<\/p><\/dd>\n<dt>Where did the \"Change All Passwords\" interface go?<\/dt>\n<dd><p>A link to the page is found in this plugin's entry in the \"Plugins\" admin\ninterface:<\/p>\n\n<ul>\n<li>Regular sites:  Plugins<\/li>\n<li>Sites using multisite networks:  My Sites | Network Admin | Plugins<\/li>\n<\/ul><\/dd>\n<dt>I just got hit with 500 failed logins! Why isn't this plugin working?!?<\/dt>\n<dd><p>Let's turn the question around: \"How long did it take to get in those 500\nhits?\"  Chances are it took hours.  (Six hours if they're attacking with one\nthread, 2 hours if they're coming at you with three threads, etc.)  If this\nplugin wasn't working, they'd have pulled it off under a minute.  Similarly,\nwithout the slowed responses this plugin provides, an attacker given six\nhours against your site could probably get in over 170,000 hits.<\/p>\n\n<p>Anyway, my real question for you is \"Did they get in?\"  I'll bet not.  The\nstrong passwords this plugin requires from your users lowers the chances of\nsomeone breaking in to just about zero.<\/p>\n\n<p>And even if they <em>do<\/em> get lucky and figure out a password, Login Security\nSolution realizes they're miscreants and kicks them out.<\/p><\/dd>\n<dt>Will you provide lock outs \/ blocks in addition to slow downs?<\/dt>\n<dd><p>If you look at it the right way, Login Security Solution provides lockouts\n(where \"lockout\" means \"denies access\" to attackers.)  Below is a comparison\nof the attack handling logic used by Limit Login Attempts and Login Security\nSolution.<\/p>\n\n<p><strong>Limit Login Attempts<\/strong><\/p>\n\n<ul>\n<li><p><em>Invalid or Valid Credentials by Attacker or Actual User<\/em><\/p>\n\n<ol>\n<li>Process authentication request (check IP address)<\/li>\n<li>Error message: \"Too many failed login attempts.\" (ACCESS DENIED.)<\/li>\n<\/ol><\/li>\n<\/ul>\n\n<p>Note, this approach means an actual user can be denied access for 12 hours after making 4 mistakes.<\/p>\n\n<p><strong>Login Security Solution<\/strong><\/p>\n\n<ul>\n<li><p><em>Invalid Credentials by Attacker or Actual User<\/em><\/p>\n\n<ol>\n<li>Process authentication request (check IP, user name, and password)<\/li>\n<li>Slow down the response<\/li>\n<li>Error message: \"Incorrect username or password.\" (ACCESS DENIED.)<\/li>\n<\/ol><\/li>\n<li><p><em>Valid Credentials by Attacker<\/em><\/p>\n\n<ol>\n<li>Process authentication request (check IP, user name, and password)<\/li>\n<li>Slow down the response<\/li>\n<li>Set force password change flag for user<\/li>\n<li>Error message: \"Your password must be reset. Please submit this form to reset it.\" (ACCESS DENIED.)<\/li>\n<\/ol><\/li>\n<li><p><em>Valid Credentials by Actual User<\/em><\/p>\n\n<ol>\n<li>Process authentication request (check IP, user name, and password)<\/li>\n<li>(If user is coming from their verified IP address, let them in, END)<\/li>\n<li>Slow down the response<\/li>\n<li>Error message: \"Your password must be reset. Please submit this form to reset it.\" (ACCESS DENIED.)<\/li>\n<li>On subsequent request... user verifies their identity via password reset process<\/li>\n<li>User's IP address is added to their verified IP list for future reference<\/li>\n<\/ol><\/li>\n<\/ul>\n\n<p>So both plugins deny access to attackers. But Login Security Solution has\nthe bonuses of letting legitimate users log in and slowing the attacks down.\nPlus LSS monitors user names, passwords, and IP's for attacks, while all of\nthe other plugins just watch the IP address.<\/p><\/dd>\n<dt>Won't the slowdowns open my website to Denial of Service (DOS) attacks?<\/dt>\n<dd><p>Yeah, the DOS potential is there.  I mitigated it for the most part by\ndisconnecting the database link (the most precious resource in most\nsituations) before sleeping.  But remember, distributed denial of service\nattacks are fairly easy to initiate these days.  If someone really wants to\nshut down your site, they'll be able to do it without even touching this\nplugin's login failure process.<\/p><\/dd>\n<dt>Where should I report bugs and feature requests?<\/dt>\n<dd><p>Development of this plugin happens on\n<a href=\"https:\/\/github.com\/convissor\/login-security-solution\">GitHub<\/a>.\nPlease submit\n<a href=\"https:\/\/github.com\/convissor\/login-security-solution\/issues\">bug and feature requests<\/a>,\n<a href=\"https:\/\/github.com\/convissor\/login-security-solution\/pulls\">pull requests<\/a>,\n<a href=\"https:\/\/github.com\/convissor\/login-security-solution\/wiki\">wiki entries<\/a>\non our GitHub.<\/p><\/dd>\n<dt>Information for Translators<\/dt>\n<dd><ol>\n<li><strong>Do not<\/strong> commit the <code>.mo<\/code> files!  They get created as part of the\nrelease process.<\/li>\n<li>Translation commits and pull requests should <strong>only<\/strong> touch the <code>.po<\/code>\nfile.  If you have other changes you wish to see made, please do so\nvia separate commits in separate pull requests.<\/li>\n<li>When translating a new feature, please make that one commit.  If other\nparts of the translation need updating, please make them in a separate\ncommit.<\/li>\n<li>Please don't change formatting inside the <code>.po<\/code> file<\/li>\n<li><strong>Run <code>git diff<\/code> before all commits.<\/strong>  Ensure only expected changes\nare being made.<\/li>\n<li>Do NOT translate items that have a comment above them saying\n    Translation from WordPress.  DO NOT TRANSLATE IT IN THIS PLUGIN.\nWhen starting a new translation, please take a look at an existing\n    .po file to see which strings they are.  Those phrases are already\ntranslated in WordPress' core.  Leaving them untranslated here ensures\nconsistency with the rest of WordPress.<\/li>\n<li><p>To start a new translation:<\/p>\n\n<pre><code>cd languages\n<\/code><\/pre><\/li>\n<\/ol><\/dd>\n<dt>Adjust \"CC\" to your country code.<\/dt>\n<dd><p>cp login-security-solution.pot login-security-solution-lc_CC.po<\/p><\/dd>\n<dt>Edit the new login-security-solution-lc_CC.po file.<\/dt>\n<dd><\/dd>\n<dt>Translation Information for Developers<\/dt>\n<dd><ul>\n<li><p>To update the <code>.pot<\/code> file:<\/p>\n\n<ol>\n<li><p>WordPress' <code>makepot<\/code> utility directory should be in the same directory\nas the <code>login-security-solution<\/code> directory.  If you don't have this\nsetup, here's what to do:<\/p>\n\n<ul>\n<li>cd into the directory above this one.<\/li>\n<li><code>svn checkout http:\/\/i18n.svn.wordpress.org\/tools\/trunk\/ makepot<\/code><\/li>\n<li><p>So, now you'll have:<\/p>\n\n<pre><code>parent dir\n    |- login-security-solution\/\n    |- makepot\/\n<\/code><\/pre><\/li>\n<\/ul><\/li>\n<li><p><code>cd login-security-solution\/languages<\/code><\/p><\/li>\n<li><code>.\/makepot.sh<\/code><\/li>\n<\/ol><\/li>\n<li><p>Then, bringing the <code>.po<\/code> files up to date is as easy as:<\/p>\n\n<ol>\n<li><code>.\/updatepos.sh<\/code><\/li>\n<\/ol><\/li>\n<li><p>Finally, to update the <code>.mo<\/code> files for testing or release:<\/p>\n\n<ol>\n<li><code>.\/makemos.sh<\/code><\/li>\n<\/ol><\/li>\n<\/ul><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.56.0 (2016-08-13)<\/h4>\n\n<ul>\n<li>Fix translation domain to be string in one __() call.<\/li>\n<\/ul>\n\n<h4>0.55.0 (2016-01-30)<\/h4>\n\n<ul>\n<li>Block discovering user names via the \"?author=\" query string<\/li>\n<\/ul>\n\n<h4>0.54.0 (2016-01-27)<\/h4>\n\n<ul>\n<li>Fix memory exhaustion on sites with many users during plugin activation\nif password history is enabled<\/li>\n<li>Put \"in\" in \"Please log and change it\"<\/li>\n<\/ul>\n\n<h4>0.53.0 (2015-09-25)<\/h4>\n\n<ul>\n<li>Change translation domain from constant to string in preparation for\nintegration with translate.wordpress.org<\/li>\n<\/ul>\n\n<h4>0.52.0 (2015-05-25)<\/h4>\n\n<ul>\n<li>Silence safe mode warnings from is_readable()<\/li>\n<li>Add Polish translation<\/li>\n<li>Add Finnish translation<\/li>\n<li>Rename Japanese translation files from <code>ja_JP<\/code> to <code>ja<\/code><\/li>\n<\/ul>\n\n<h4>0.51.0 (2015-03-15)<\/h4>\n\n<ul>\n<li>Security Fixes:\n\n<ul>\n<li>Remove calls to <code>dict<\/code>. Parse <code>dict<\/code> file if available instead.<\/li>\n<li>Remove use of <code>grep<\/code>.<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>0.50.0 (2014-12-25)<\/h4>\n\n<ul>\n<li>Take advantage of WP 4.1's new password_hint filter<\/li>\n<li>Add Italian translation<\/li>\n<\/ul>\n\n<h4>0.49.0 (2014-11-10)<\/h4>\n\n<ul>\n<li>Fix password policy hint on password reset form broken by changes in WP<\/li>\n<\/ul>\n\n<h4>0.48.0 (2014-10-17)<\/h4>\n\n<ul>\n<li>Fix \"DoS Tier\" setting validation so it can be set to 0.<\/li>\n<\/ul>\n\n<h4>0.47.0 (2014-10-15)<\/h4>\n\n<ul>\n<li>Add the \"DoS Tier,\" above \"Delay Tier 3,\" beyond which respones are no\nlonger slowed down, keeping sites from befalling Denial of Service conditions<\/li>\n<li>Add the \"Deletion Interval\" and \"Deletion Days\" settings for\nautomatically removing old data<\/li>\n<li>Added \"action\" hooks:\n\n<ul>\n<li>login_security_solution_insert_fail<\/li>\n<li>login_security_solution_notify_breach<\/li>\n<li>login_security_solution_notify_fail<\/li>\n<li>login_security_solution_fail_tier_dos<\/li>\n<\/ul><\/li>\n<li>Added \"filter\" hooks. See \"Hooks\" in the \"Installation\" tab for more info.\n\n<ul>\n<li>login_security_solution_notify_breach_subject<\/li>\n<li>login_security_solution_notify_breach_message<\/li>\n<li>login_security_solution_notify_breach_user_subject<\/li>\n<li>login_security_solution_notify_breach_user_message<\/li>\n<li>login_security_solution_notify_fail_subject<\/li>\n<li>login_security_solution_notify_fail_message<\/li>\n<\/ul><\/li>\n<li>Escape WP's <code>table_prefix<\/code> before use<\/li>\n<li>Use WP's remove_submenu_page() (instead of using an empty title) to keep\nChange All Passwords off the settings menu<\/li>\n<li>Add label\/id for settings fields<\/li>\n<\/ul>\n\n<h4>0.46.0 (2014-10-03)<\/h4>\n\n<ul>\n<li>Fix password policy hint broken by changes in WP 3.9<\/li>\n<li>Adjust unit tests for new auth cookie format in WP 4.0<\/li>\n<\/ul>\n\n<h4>0.45.0 (2014-08-17)<\/h4>\n\n<ul>\n<li>Adjust for password reset process for security changes in WP 3.9.2<\/li>\n<\/ul>\n\n<h4>0.44.0 (2014-05-30)<\/h4>\n\n<ul>\n<li>Handle mysqli usage<\/li>\n<li>Indicate that setting \"Match Time\" to 0 disables slowdowns, notifications,\nand breach confirmations.<\/li>\n<li>If \"Match Time\" is 0, return empty values rather than running queries.<\/li>\n<\/ul>\n\n<h4>0.43.0 (2014-01-16)<\/h4>\n\n<ul>\n<li>By popular demand, notification emails now include the full IP address.<\/li>\n<\/ul>\n\n<h4>0.42.0 (2013-07-06)<\/h4>\n\n<ul>\n<li>Have Maintenence Mode messaging say who turned it on and how to turn it off.<\/li>\n<li>Added pw_sequence for German T1 keyboard layout. (cfoellmann)<\/li>\n<\/ul>\n\n<h4>0.41.0 (2013-06-26)<\/h4>\n\n<ul>\n<li>Fix \"authenticate filter not called\" when auth process lacks a user name.<\/li>\n<\/ul>\n\n<h4>0.40.0 (2013-06-22)<\/h4>\n\n<ul>\n<li>Track the age of verified IP's and use that to prevent users being locked\nout by \"attacks\" from one's own IP address.<\/li>\n<li>Unit tests pass using PHP 5.3.27-dev, 5.4.17-dev, 5.5.0-dev<\/li>\n<li>Tested under WordPress 3.4.2, 3.5.2 and 3.6beta4 using regular and multisite.<\/li>\n<\/ul>\n\n<h4>0.39.0 (2013-05-29)<\/h4>\n\n<ul>\n<li>Enforce password history during password reset process.<\/li>\n<\/ul>\n\n<h4>0.38.0 (2013-05-27)<\/h4>\n\n<ul>\n<li>Mention that the password force change process does not touch the admin\nthat presses the button.<\/li>\n<li>Remove HTML special characters when using WP's <code>blogname<\/code> setting.<\/li>\n<li>Unit tests pass using PHP 5.3.27-dev, 5.4.17-dev, 5.5.0-dev<\/li>\n<li>Tested under WordPress 3.5.1 and 3.6beta3 using regular and multisite.<\/li>\n<\/ul>\n\n<h4>0.37.0 (2013-04-29)<\/h4>\n\n<ul>\n<li>Monitor login attempts from XML-RPC requests.<\/li>\n<li>Fix \"te ernstig te\" in the Dutch translation (thanks fwieringen@github).<\/li>\n<\/ul>\n\n<h4>0.36.0 (2013-04-13)<\/h4>\n\n<ul>\n<li>Have the password reset page say why a password isn't strong enough.<\/li>\n<li>Add Dutch translation.<\/li>\n<\/ul>\n\n<h4>0.35.0 (2013-02-22)<\/h4>\n\n<ul>\n<li>Don't track cookie failures if name or hash is empty.<\/li>\n<li>Add German translation.<\/li>\n<li>Update French translation.<\/li>\n<li>Documentation improvements.<\/li>\n<\/ul>\n\n<h4>0.34.0 (2012-10-21)<\/h4>\n\n<ul>\n<li>Have <code>login_errors<\/code> filter check <code>$wp_error<\/code> also, not just <code>$errors.<\/code><\/li>\n<li>Skip <code>exec()<\/code> calls if <code>safe_mode<\/code> is on.<\/li>\n<li>Unit tests pass using WordPress 3.5 RC2 under PHP 5.4.5-dev and 5.3.19-dev.<\/li>\n<\/ul>\n\n<h4>0.33.0 (2012-10-18)<\/h4>\n\n<ul>\n<li>Add text to failure alerts saying the attacker will be denied access.<\/li>\n<li>Have failure alerts say there won't be further emails.<\/li>\n<\/ul>\n\n<h4>0.32.0 (2012-10-04)<\/h4>\n\n<ul>\n<li>SIGNIFICANT CHANGE:  Reduce the number of emails sent to administrators:\nadd the \"Multiple Failure Notifications\" setting and make the default \"No.\"<\/li>\n<li>Remove the (superfluous) \"If it WAS YOU...\" part of the user notification\nemails.<\/li>\n<li>Use <code>wp_cache_flush()<\/code> in unit tests, <code>wp_cache_reset()<\/code> deprecated in 3.5.<\/li>\n<li>Unit tests pass using PHP 5.4.5-dev, 5.3.16-dev.<\/li>\n<li>Tested under WordPress 3.4.2 and 3.5beta1 using regular and multisite.<\/li>\n<\/ul>\n\n<h4>0.31.0 (2012-09-25)<\/h4>\n\n<ul>\n<li>Have breach notification emails detail the exact situation depending on\nthe system's settings.<\/li>\n<\/ul>\n\n<h4>0.30.0 (2012-09-17)<\/h4>\n\n<ul>\n<li>Translate \"Confirm\" and \"No thanks\" phrases on the settings screen.<\/li>\n<li>Adjust readme to indicate that development has moved to\n<a href=\"https:\/\/github.com\/convissor\/login-security-solution\">GitHub<\/a>.<\/li>\n<\/ul>\n\n<h4>0.29.0 (2012-09-17)<\/h4>\n\n<ul>\n<li>Adjust formatting of the <code>CREATE TABLE<\/code> statement in <code>activate()<\/code> to prevent\nWordPress' <code>dbDelta()<\/code> from creating duplicate keys each time the plugin is\nactivated.<\/li>\n<\/ul>\n\n<h4>0.28.1 (2012-09-15)<\/h4>\n\n<ul>\n<li>Update <code>.mo<\/code> translation files.<\/li>\n<\/ul>\n\n<h4>0.28.0 (2012-09-15)<\/h4>\n\n<ul>\n<li>Remove loophole:  slow down successful logins as well (for non-verified\nIP addresses).  Keeps attackers from using timeouts to skip our delayed\nresponses to failed login attempts.<\/li>\n<li>Reduce false positives for breach notifications and password resets:\n\n<ul>\n<li>Allow users through without incident if the user's Network IP failure\ncount is less than the \"Breach Email Confirm\" setting.  The old\nbehavior was to do so only if the Network IP failure count was 0.<\/li>\n<li>Add user's current IP to their verified IP list whenever they save\ntheir profile page, not just when they change their password.<\/li>\n<li>Fix when user notifications are sent.  Do so if the IP address is\nNOT verified instead of if the IP address IS verified.  Duh.<\/li>\n<li>Don't notify administrators of a successful login if the user is\ncoming in from a verified IP address.<\/li>\n<li>Change subject line of user notification emails to differentiate them\nfrom emails sent to admins.<\/li>\n<li>Reword user notification email and have it explain how to reduce\nfuture hassles.<\/li>\n<\/ul><\/li>\n<li>Remove URIs from user notification email to avoid phishing imitations.<\/li>\n<li>Add pt_BR translation.  Thanks to Valdir Trombini.<\/li>\n<li>Put plugin version number in admin notification emails.<\/li>\n<li>Update the fr_FR translation: update password policy, add settings page.<\/li>\n<li>Put Unicode flag on the two preg calls that didn't have it.  Fixes\npassword parsing problem on Windows.<\/li>\n<li>Add date to log() messages.<\/li>\n<li>Unit tests pass using PHP 5.4.5-dev, 5.3.16-dev, and 5.2.18-dev.<\/li>\n<li>Tested under WordPress 3.4.2 using regular and multisite.<\/li>\n<li>Also tested on Windows 7 using WordPress 3.4.1 and PHP 5.4.5 with mbstring\nenabled and disabled.<\/li>\n<\/ul>\n\n<h4>0.27.0 (2012-09-04)<\/h4>\n\n<ul>\n<li>Remove the password policy explanation link added in 0.26.0.<\/li>\n<\/ul>\n\n<h4>0.26.0 (2012-09-01)<\/h4>\n\n<ul>\n<li>Put a link in the password policy to an explanation of why it's necessary.<\/li>\n<\/ul>\n\n<h4>0.25.0 (2012-08-30)<\/h4>\n\n<ul>\n<li>Load text domain for password policy on password reset page.<\/li>\n<li>Have password policy mention that it can't contain words related to\nthe user or the website.<\/li>\n<\/ul>\n\n<h4>0.24.0 (2012-08-29)<\/h4>\n\n<ul>\n<li>Keep the password strength indicator from being enabled.<\/li>\n<li>Narrow down when the password policy text filter is enabled.<\/li>\n<\/ul>\n\n<h4>0.23.0 (2012-08-24)<\/h4>\n\n<ul>\n<li>Split user and site info into components before comparing them.<\/li>\n<li>Increase minimum password length to 10 characters.<\/li>\n<\/ul>\n\n<h4>0.22.0 (2012-08-17)<\/h4>\n\n<ul>\n<li>Track a given IP, user name, password combination only once.<\/li>\n<li>Prevent \"not a valid MySQL-Link resource\" on auth cookie failure.<\/li>\n<li>Increase default value of login_fail_notify from 20 to 50.<\/li>\n<li>Add partial French translation.  Settings page needs doing.  Thanks\n<a href=\"https:\/\/profiles.wordpress.org\/mermouy\">mermouy<\/a>!<\/li>\n<\/ul>\n\n<h4>0.21.0 (2012-08-07)<\/h4>\n\n<ul>\n<li>Fix is_pw_outside_ascii() to permit spaces.<\/li>\n<li>In multisite mode, send notifications to network admin, not blog admin.<\/li>\n<li>Add \"Notifications To\" setting for admins to specify the email addresses\nthe failure and breach notifications get sent to. (Request #1560)<\/li>\n<li>Clarify that the Change All Passwords link just goes to the UI.<\/li>\n<li>Get all unit tests to pass when mbstring isn't enabled.<\/li>\n<li>Internationalize the unit tests.<\/li>\n<li>Rename admin.inc to admin.php.<\/li>\n<li>Rename temporary files holding actual test results. (Bug #1552 redux)<\/li>\n<li>Unit tests pass using PHP 5.4.5-dev, 5.3.16-dev, and 5.2.18-dev.<\/li>\n<li>Tested under WordPress 3.4.1 using regular and multisite.<\/li>\n<li>Also tested on Windows 7 using PHP 5.4.5 and WordPress 3.4.1.<\/li>\n<\/ul>\n\n<h4>0.20.2 (2012-07-12)<\/h4>\n\n<ul>\n<li>Ugh, update the translation pot file.<\/li>\n<\/ul>\n\n<h4>0.20.1 (2012-07-12)<\/h4>\n\n<ul>\n<li>Add \"numbers\" to the password policy text.<\/li>\n<\/ul>\n\n<h4>0.20.0 (2012-07-12)<\/h4>\n\n<ul>\n<li>Replace WP's password policy text with our own.<\/li>\n<\/ul>\n\n<h4>0.19.0 (2012-07-11)<\/h4>\n\n<ul>\n<li>Remove inadvertent log call added in 0.17.0.<\/li>\n<\/ul>\n\n<h4>0.18.0 (2012-07-11)<\/h4>\n\n<ul>\n<li>Keep legit user from having to repeatedly reset pw during active attacks\nagainst their user name.<\/li>\n<\/ul>\n\n<h4>0.17.0 (2012-07-09)<\/h4>\n\n<ul>\n<li>Fix network IP query in get_login_fail(). (Bug #1553,\n<a href=\"https:\/\/profiles.wordpress.org\/deanmarktaylor\">deanmarktaylor<\/a>)<\/li>\n<li>Rename files holding expected test results. (Bug #1552,\n<a href=\"https:\/\/profiles.wordpress.org\/deanmarktaylor\">deanmarktaylor<\/a>)<\/li>\n<\/ul>\n\n<h4>0.16.0 (2012-07-08)<\/h4>\n\n<ul>\n<li>Have shell script gracefully handle value already being the desired value.<\/li>\n<\/ul>\n\n<h4>0.15.0 (2012-07-06)<\/h4>\n\n<ul>\n<li>Log auth cookie failures too.<\/li>\n<li>Clean up sleep logic. (Bug #1549,\n<a href=\"https:\/\/profiles.wordpress.org\/deanmarktaylor\">deanmarktaylor<\/a>)<\/li>\n<\/ul>\n\n<h4>0.14.0 (2012-07-05)<\/h4>\n\n<ul>\n<li>Fix emails being mistakenly sent in multisite mode that say \"There have\nbeen at least 0 failed attempts to log in\".  (Bug #1548,\n<a href=\"https:\/\/profiles.wordpress.org\/deanmarktaylor\">deanmarktaylor<\/a>)<\/li>\n<li>Add an <code>.htaccess<\/code> file that blocks access to this plugin's directory.<\/li>\n<\/ul>\n\n<h4>0.13.0 (2012-07-01)<\/h4>\n\n<ul>\n<li>Add a script for turning our \"Disable Logins\" feature on and off from the\ncommand line.<\/li>\n<\/ul>\n\n<h4>0.12.0 (2012-06-30)<\/h4>\n\n<ul>\n<li>Display a notice on top of admin pages when our maintenance mode is enabled.<\/li>\n<\/ul>\n\n<h4>0.11.0 (2012-06-28)<\/h4>\n\n<ul>\n<li>Use <code>POST<\/code> value for <code>$user_name<\/code> in <code>login_errors()<\/code> because global value\nisn't always set.<\/li>\n<li>Add some more (commented out) log() calls to help users help me help them.<\/li>\n<\/ul>\n\n<h4>0.10.0 (2012-06-16)<\/h4>\n\n<ul>\n<li>Catch $user_ID not being set during \"Change All Passwords\" submission.<\/li>\n<li>Add (commented out) log() calls in important spots. Enables users to\nhelp me help them.<\/li>\n<\/ul>\n\n<h4>0.9.0 (2012-06-16)<\/h4>\n\n<ul>\n<li>Fix change that prevented users from logging in after using the password\nreset process with an insecure password. Users can now pick a better\npassword right on the spot.<\/li>\n<li>Regenerate translation POT file.<\/li>\n<li>Tested under WordPress 3.3.2 and 3.4RC3, both using regular and multisite.<\/li>\n<li>Unit tests pass using PHP 5.4.0RC8-dev, 5.3.11-dev, and 5.2.18-dev.<\/li>\n<\/ul>\n\n<h4>0.8.0 (2012-04-29)<\/h4>\n\n<ul>\n<li>Fix logging user out a second time after WordPress expires cookies.<\/li>\n<li>It turns out this plugin requires WordPress 3.3, not 3.0.<\/li>\n<li>Tested under WordPress 3.3.2 regular and 3.4beta2 multisite.<\/li>\n<li>Unit tests pass using PHP 5.4.0RC8-dev, 5.3.11-dev, and 5.2.18-dev.<\/li>\n<\/ul>\n\n<h4>0.7.0 (2012-04-25)<\/h4>\n\n<ul>\n<li>The \"lost your password\" process now validates passwords.<\/li>\n<li>Tested under WordPress 3.3.1 regular and 3.4beta2 multisite.<\/li>\n<li>Unit tests pass using PHP 5.4.0RC8-dev, 5.3.11-dev, and 5.2.18-dev.<\/li>\n<\/ul>\n\n<h4>0.6.1 (2012-04-19)<\/h4>\n\n<ul>\n<li>Minor wording adjustments.<\/li>\n<\/ul>\n\n<h4>0.6.0 (2012-04-18)<\/h4>\n\n<ul>\n<li>Use <code>ENT_QUOTES<\/code> instead of <code>ENT_COMPAT<\/code> in <code>htmlspecialchars()<\/code> calls\nbecause WordPress mixes and matches the double and single quotes to\ndelimit attributes.<\/li>\n<li>Tested under WordPress 3.3.1 regular and 3.4beta2 multisite.<\/li>\n<li>Unit tests pass using PHP 5.4.0RC8-dev, 5.3.11-dev, and 5.2.18-dev.<\/li>\n<\/ul>\n\n<h4>0.5.0 (2012-04-18)<\/h4>\n\n<ul>\n<li>Have multisite network mode use the saved options instead of the defaults.<\/li>\n<li>Close more HTML injection vectors.  (One would think WordPress' built in\nfunctions would already do this.  Alas...)<\/li>\n<li>Get the success\/error messages to work when saving settings via the\nNetwork Admin page.<\/li>\n<li>Improve unit tests by ensuring the fail table uses InnoDB.<\/li>\n<li>Tested under WordPress 3.3.1 regular and 3.4beta2 multisite.<\/li>\n<li>Unit tests pass using PHP 5.4.0RC8-dev, 5.3.11-dev, and 5.2.18-dev.<\/li>\n<\/ul>\n\n<h4>0.4.0 (2012-04-17)<\/h4>\n\n<ul>\n<li>Add multisite network support.<\/li>\n<li>Keep unit tests from deleting settings.  Note: removes the ability to\nrun the unit tests without activating the plugin.<\/li>\n<li>Tested under WordPress 3.3.1 regular and 3.4beta2 multisite.<\/li>\n<li>Unit tests pass using PHP 5.4.0RC8-dev, 5.3.11-dev, and 5.2.18-dev.<\/li>\n<\/ul>\n\n<h4>0.3.0 (2012-04-04)<\/h4>\n\n<ul>\n<li>Use UTF-8 encoding for <code>htmlspecialchars()<\/code> instead of <code>DB_CHARSET<\/code>.<\/li>\n<li>Tested under WordPress 3.3.1.<\/li>\n<li>Unit tests pass using PHP 5.4.0RC8-dev, 5.3.11-dev, and 5.2.18-dev.<\/li>\n<\/ul>\n\n<h4>0.2.1 (2012-04-03)<\/h4>\n\n<ul>\n<li>Ensure all files are in the state I intended.  Needed because\nWordPress' plugin site automatically rolls releases.<\/li>\n<\/ul>\n\n<h4>0.2.0 (2012-04-03)<\/h4>\n\n<ul>\n<li>Utilize the $encoding parameter of <code>htmlspecialchars()<\/code> to avoid\nproblems under PHP 5.4.<\/li>\n<li>Tested under WordPress 3.3.1.<\/li>\n<li>Unit tests pass using PHP 5.4.0RC8-dev, 5.3.11-dev, and 5.2.18-dev.<\/li>\n<\/ul>\n\n<h4>0.1.0 (2012-03-26)<\/h4>\n\n<ul>\n<li>Beta release.<\/li>\n<\/ul>\n\n<h4>0.0.4 (2012-03-22)<\/h4>\n\n<ul>\n<li>Initial import to <code>plugins.svn.wordpress.org<\/code>.<\/li>\n<\/ul>\n\n<h4>0.0.3<\/h4>\n\n<ul>\n<li>Fix mix ups in the code saving the \"Change All Passwords\" admin UI.<\/li>\n<li>Adjust IdleTest so it doesn't radically change <code>wp_users<\/code> auto increment.<\/li>\n<li>Tested under WordPress 3.3.1.<\/li>\n<li>Unit tests pass using PHP 5.4.0RC8-dev, 5.3.11-dev, and 5.2.18-dev.<\/li>\n<\/ul>\n\n<h4>0.0.2<\/h4>\n\n<ul>\n<li>Use Unicode character properties to improve portability.<\/li>\n<li>Stop tests short if not in a WordPress install.<\/li>\n<li>Skip <code>dict<\/code> test if <code>dict<\/code> not available.<\/li>\n<li>Skip database tests if transactions are not available.<\/li>\n<li>Tested under WordPress 3.3.1.<\/li>\n<li>Unit tests pass using PHP 5.4.0RC8-dev, 5.3.11-dev, and 5.2.18-dev.<\/li>\n<\/ul>\n\n<h4>0.0.1 (2012-03-19)<\/h4>\n\n<ul>\n<li>Post the code for public review.<\/li>\n<li>Tested under WordPress 3.3.1.<\/li>\n<\/ul>","raw_excerpt":"Security against brute force attacks by tracking IP, name, password; requiring very strong passwords. Idle timeout. Maintenance mode lockdown.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/900","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=900"}],"author":[{"embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/convissor"}],"wp:attachment":[{"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=900"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=900"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=900"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=900"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=900"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=900"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}