Select one or more tags, then press “Search Plugins”

Find Plugin with any / all of the selected criteria
Search Plugin

DoctorX Hardening Wordpress Plugin - Rating, Reviews, Demo & Download

DoctorX Hardening Preview Wordpress Plugin - Rating, Reviews, Demo & Download
No ratings yet
Free
Follow for free plugins, new theme releases and theme news

Plugin Description

Out of the box, WordPress tells anyone who asks which user accounts exist and which plugins answer on your site, and one stolen password is enough to get in. DoctorX Hardening closes those doors.

  • Hides the list of user accounts from visitors. People who are not signed in can no longer read usernames from /wp-json/wp/v2/users.
  • Keeps usernames out of author pages and links. Author pages and ?author=1 style addresses go to the home page (whether or not the account exists, so the answer gives nothing away). Author links point to the home page, authors are left out of the built-in sitemap, and comments by signed-in users no longer carry the username as a CSS class.
  • No guessed pages for language-style addresses. When someone types /fr/ or /en-us/ and there is no such page, WordPress normally sends them to whatever page name happens to start with those letters. They now get a plain “not found” instead.
  • Hides the list of what your site can do. WordPress answers anyone who asks /wp-json/ with every address of every plugin on the site: a map of what is installed and where to probe. Visitors, and signed-in customers or subscribers, now get that answer without the list. People who work on the site (who can edit posts or other entries), and apps signed in as them, still get all of it.
  • Two-step sign-in. Each person can add a second step to their own sign-in: a six-digit code from an authenticator app on their phone (the standard kind, RFC 6238, that every authenticator app and most password managers make). Ten backup codes cover the day the phone is not at hand.
  • A security.txt file. The internet standard (RFC 9116) for telling people who find a security problem whom to tell. Give a contact. The plugin serves the file with the date the standard asks for, reminds you before that date runs out, and takes the file down if you do not confirm the contact.

  • An activity record (off until you switch it on). Who did what on the site, and when. It records sign-ins and failed sign-ins (with the address they came from, the addresses a proxy passed on, the browser, the name that was tried, and whether they came through XML-RPC). It also records posts, pages, media, plugins, themes, updates, settings, users and roles, comments, menus, widgets, Site Health, exports and privacy requests. Twenty failed sign-ins from one address in an hour are one line with a count, not twenty. You get a screen under Tools Activity with filters and a download as CSV or JSON, a box on the dashboard, a link in the admin bar, an RSS feed opened with a secret and a weekly email, each one optional. It can bring in the events Simple History recorded, so that plugin can go. On its “More settings” screen, each of these is off until you switch it on:

    • alerts by email, Slack, Discord, Telegram, Microsoft Teams or a webhook (ready rules or your own)
    • forwarding of every event to syslog, Datadog, Splunk or a webhook
    • log files as JSON Lines, logfmt or syslog lines
    • notes on events, and entries added by hand
    • who may see the record (roles, or only people you name)
    • which events to leave out
    • the request’s details on each event while you look into something
    • events made from what is already on the site
    • where an address is (from a database file on your server, or ipinfo.io with your own token), and a map of sign-ins
    • what other plugins do (WooCommerce, Gravity Forms, WPForms, Elementor, Advanced Custom Fields, Redirection, Jetpack and more)
    • emails sent, outside requests, scheduled jobs and REST requests
    • a richer screen, busy hours and any dates on History insights, and more download formats.

One screen: Settings Hardening. The switches are on when you activate the plugin. Untick anything you don’t want. Two-step sign-in changes nothing for anybody until they set it up for themselves under Users (or Profile) Two-step sign-in. There is no security.txt until you give a contact.

The plugin needs nothing else, works with any theme, and sends nothing to anybody outside your site: its emails go to your own people, and the picture you scan to set up two-step sign-in is drawn by your own browser. (The one exception is the Cloudflare part below, which talks to Cloudflare only after you save a Cloudflare token of your own.)

Every feature is free and works fully. There is no paid version of this plugin.

Sign-in and server (each part off until you switch it on)

A second tab, Settings Hardening Sign-in and server, holds stronger protections. Nothing on it is on until you switch it on, and each part says how to undo it.

  • Password-guess lockout. An internet address that fails to sign in five times in 24 hours may not sign in for 30 days. One that tries an account name that does not exist (“admin”) is paused at once. An address an administrator signed in from in the last 30 days is only ever paused for an hour. Your trusted addresses, the server itself and private networks are not paused. A paused address cannot sign in even with the right password, but the rest of the site is not affected. Every number can be changed. It stands aside where Wordfence’s own sign-in lockout is on.
  • One message for a wrong name and a wrong password, and a “Lost your password?” answer that does not say whether an account exists.
  • Small doors shut, one switch each: application passwords, XML-RPC, author names in embeds, the WordPress version in the page head and in the addresses of WordPress’s own files.
  • Two-step sign-in required for the roles you choose, from a date you choose: before it, signing in opens the set-up screen with a note of the date, and after it the set-up screen comes first (their profile, signing out and the set-up buttons keep working).
  • “Email me a code instead” on the code page, for somebody without their phone: eight digits to the account’s own address, once, for ten minutes, counted under the same limits as wrong codes from the app. A plugin that sends texts can offer “Text me a code” through a filter.
  • A hidden sign-in door. The sign-in page answers at an address of your choosing. Strangers who ask for wp-login.php or /wp-admin/ get “not found”. These keep working: links that set a new password (also ones emailed before), signing out, protected posts, everybody signed in, the site’s forms, the REST API, XML-RPC, scheduled jobs, WP-CLI and WordPress’s recovery-mode link after a fatal error. The new address is emailed to the administration address. It is not shown to a stranger. A “Log in” link, “log in to reply” or a plugin sending a visitor to the sign-in page keep wp-login.php, which answers that visitor “not found”. People signed in see the new address, and a browser that came through the door before is taken to it.
  • Probe ban. An address that asks for three different scanner-only addresses (.env, .git, copies of wp-config.php, phpMyAdmin, database dumps) within an hour is refused by the whole site for seven days. Search engines, AI crawlers and trusted addresses are not counted.
  • Cloudflare edge rules, with a Cloudflare token of your own (sealed with your site’s keys, not shown again). They block scanner probes and Google or Bing agents that Cloudflare does not verify, put a “checking your browser” step in front of the sign-in page, and limit sign-in posts to 5 in 10 seconds per address. You see the difference first. Nothing changes at Cloudflare until you press Apply. Undo takes back only what Apply (or Copy) did: the DoctorX rules it added are removed and those it changed are put back, while rules you add or change in Cloudflare’s dashboard afterwards are left alone. Copy the rules to your other zones, send the probe ban list to Cloudflare, and have Cloudflare forget a page when it changes. Crawlers Cloudflare verifies, /.well-known/, /wp-json/, feeds and your trusted addresses are left alone. Nothing touches Bot Fight Mode, caching or search settings.
  • Lines for your web server. nginx and Apache lines to copy or download: files that should not be fetched, no PHP in uploads, security headers, a slower sign-in page for guessers, a flood limit that exempts verified crawlers, a verified-crawler lane with a weekly refresh script, a friendly page when PHP is down, “only through Cloudflare”, and wp-config lines for HTTPS behind a proxy. WordPress cannot change the web server: you or your host put them in place. Nothing in them turns away a search engine or an AI assistant.
  • A daily self-check. The site asks itself over its own address, as a visitor would, whether the private folders of DoctorX products refuse the web (a small probe file is put in each and deleted at once), and whether a proxy or CDN in front of the site gives a private answer to the next visitor. A problem shows on the Sign-in and server tab with the lines that fix it. It only reads and changes nothing. A site that cannot reach its own address skips it, and the screen says so.

External services

Nothing in this plugin talks to an outside service until you ask it to. None of the outside services below is used on a website set up not to send (DOCTORX_HARDENING_MAY_CONNECT set to false, or the doctorx_hardening_may_connect filter), such as a staging copy, except WordPress.org’s checksums, which WordPress itself also fetches.

  • Cloudflare API (https://api.cloudflare.com/client/v4), only after you save a Cloudflare API token of your own on Settings Hardening Sign-in and server, and only for what you press there or switch on. That is:

    • listing the zones the token can see
    • reading a zone’s custom firewall and rate-limit rules (Preview)
    • reading the zone’s cache rules, once a day, for the self-check (read only)
    • adding, changing or putting back rules (Apply, Undo, Copy)
    • sending the probe ban’s addresses as IP access rules (Send them now)
    • with “When a page changes, have Cloudflare forget it” (or DoctorX Command Center’s “Empty caches”), the addresses of changed pages or a “forget everything” request.

    Sent: the token (as the request’s authorisation), the zone’s id, the rules this plugin generates (your host names, your trusted addresses, the hidden door’s address when it is on), banned internet addresses, and page addresses. Nothing about your visitors or accounts is sent. Cloudflare’s terms: https://www.cloudflare.com/website-terms/ and privacy policy: https://www.cloudflare.com/privacypolicy/

  • ipinfo.io (https://ipinfo.io), only when you choose “ipinfo.io” under “Where addresses are” on the activity record’s More settings screen, save your own token, and an administrator opens an address in the record: that one internet address and your token. ipinfo’s terms: https://ipinfo.io/terms-of-service and privacy policy: https://ipinfo.io/privacy-policy
  • Google Maps Static API (https://maps.googleapis.com), only when you switch on the sign-in map and save your own Google Maps key, and only when an administrator opens the map. Sent: up to 60 rounded map points (latitude and longitude to three decimals, about 100 metres) and your key. No addresses, names or accounts are sent. Google’s terms: https://cloud.google.com/maps-platform/terms and privacy policy: https://policies.google.com/privacy
  • Alerts, only to the destinations you add on the activity record’s More settings screen (Alerts) and only for the rules you set. Sent: the alert’s subject, text and a link to the record. For a webhook, also your site’s address, the rule’s name and the event (as below). The destinations can be:
    • Slack (the webhook address you paste). Terms https://slack.com/main-services-agreement and privacy https://slack.com/trust/privacy/privacy-policy
    • Discord. Terms https://discord.com/terms and privacy https://discord.com/privacy
    • Microsoft Teams. Terms https://www.microsoft.com/en-us/servicesagreement and privacy https://www.microsoft.com/en-us/privacy/privacystatement
    • Telegram (api.telegram.org with your bot’s token and chat). Terms https://telegram.org/tos and privacy https://telegram.org/privacy
    • any address of your own that takes JSON, signed with your secret if you set one.
  • Log forwarding, only when you switch it on on the activity record’s More settings screen and switch on a destination with its connection details. Sent: every event as it is written, with its date, kind, level, message, who did it (user id, login and email address), the internet address and any addresses passed on by a proxy, the browser’s user agent, what it was about, the event’s details and your site’s address. (Writing to this server’s own system log is not an outside service and also happens on a website set up not to send.) The destinations can be:
    • this server’s own system log
    • a syslog server you name (UDP, TCP or TLS)
    • Datadog’s Logs API with your key. Terms https://www.datadoghq.com/legal/terms/ and privacy https://www.datadoghq.com/legal/privacy/
    • Splunk’s HTTP Event Collector with your token. Terms https://www.splunk.com/en_us/legal/splunk-general-terms.html and privacy (Splunk is part of Cisco) https://www.cisco.com/site/us/en/about/legal/privacy.html
    • any webhook address of yours.
  • WordPress.org (https://api.wordpress.org), only when you switch on “Check WordPress’s own files once a day” in the activity record’s settings: once a day, your WordPress version and language, to fetch the official checksums of WordPress’s files (the same request WordPress makes for its own updates). WordPress.org’s privacy policy: https://wordpress.org/about/privacy/
  • Your server’s DNS resolver, only when you switch on “Also ask for the address’s host name” and an administrator opens an address in the record: that one internet address, to look up its host name (reverse DNS).
  • The emails this plugin sends (sign-in codes, the hidden door’s address, notes about two-step sign-in) go through your site’s own mail setup to your own people.
  • Your own site’s address, once a day, for the self-check: a few requests to your own site (a probe file in each private folder and a private probe page), which pass through your proxy or CDN if you have one. Nothing is sent to anybody else.
  • The crawler-list script on the “Lines for your web server” screen is a file you download and run on your server yourself: it fetches the address lists Google, Bing and Cloudflare publish (developers.google.com, www.bing.com, www.cloudflare.com). The plugin itself does not fetch them.

Source code and credits

All code is included unminified. The picture you scan when setting up two-step sign-in is drawn in the browser by QR Code Generator for JavaScript by Kazuhiko Arase (MIT licence), included unchanged in assets/vendor/qrcode-generator.js. The word “QR Code” is a registered trademark of DENSO WAVE INCORPORATED.

Made by DoctorX.ca.

Screenshots

  1. Settings → Hardening: each protection with its own switch.

    Settings → Hardening: each protection with its own switch.

  2. Setting up two-step sign-in: scan the code with an authenticator app, then type the code it shows.

    Setting up two-step sign-in: scan the code with an authenticator app, then type the code it shows.

  3. The sign-in page asks for the six-digit code after the password.

    The sign-in page asks for the six-digit code after the password.

  4. The activity record (Tools → Activity): who did what on the site, with filters and downloads.

    The activity record (Tools → Activity): who did what on the site, with filters and downloads.

  5. History insights: events a day, failed sign-ins and the most active people.

    History insights: events a day, failed sign-ins and the most active people.


Reviews & Comments