Skip to content
WPExpertsHub
  • Plugins
  • WooCommerce
  • Services
  • Support
0 Explore Plugins
Esc

Popular User Security Guard for WordPress Media and Database Cleaner for WordPress Backup & Restore by WpExperts Hub

  • Plugins
  • WooCommerce
  • Services
  • Support
  • Cart (0)
Explore Plugins My Account
  1. Home
  2. Blog
  3. How to Add an Image Code to WordPress Login and WooCommerce Forms

How to Add an Image Code to WordPress Login and WooCommerce Forms

Published 13 October 2026 · 10 min read

On this page

  1. 01What an image code does, and what it leaves alone
  2. 02Which forms get a code
  3. 03What you need
  4. 04Step-by-step setup
  5. 05What the visitor sees
  6. 06How the code is made and checked
  7. 07Accessibility and fallback
  8. 08Caching, CDNs and proxies
  9. 09What it does not stop
  10. 10Good to know and troubleshooting
  11. 11Links
In short

Add a self-hosted image code to WordPress and WooCommerce login, registration, lost-password, comment and review forms, and learn what it stops, what it does not and how caching affects it.

Contents11 sections
  1. 01What an image code does, and what it leaves alone
  2. 02Which forms get a code
  3. 03What you need
  4. 04Step-by-step setup
  5. 05What the visitor sees
  6. 06How the code is made and checked
  7. 07Accessibility and fallback
  8. 08Caching, CDNs and proxies
  9. 09What it does not stop
  10. 10Good to know and troubleshooting
  11. 11Links

To stop bots on your WordPress and WooCommerce forms without a captcha service, install Protect Login Forms for WordPress & WooCommerce. It asks visitors to type the characters shown in an image before a form is processed, and the image is drawn on your own server. All eight forms it covers are switched on when you activate it, as long as your server has PHP GD with FreeType. Two things to know before you rely on it: exclude the form pages from any CDN or server cache, and remember that an image code stops bots that cannot read it, not determined attackers, and has no audio alternative.

What an image code does, and what it leaves alone

A bot that cannot read the image is refused when it tries to create a fake account, post a comment or submit a login form, even with a correct password. The image is made with PHP GD and a bundled font, so there is no captcha account, no API key, no request to another service when a form is shown or checked, no cookie and no script of its own. The licence and update check is the only outside contact.

It does not limit login attempts, lock accounts, block IP addresses or log anything. For that, see our tutorial on how to limit login attempts on WordPress.

Which forms get a code

Each of the eight forms has its own checkbox under Settings → Protect Login Forms, and all are on by default.

  • Login form: the form on wp-login.php and forms printed by wp_login_form().
  • Registration form: shown by WordPress only when Settings → General → Membership → Anyone can register is ticked.
  • Lost password form: the reset request on wp-login.php. A wrong code stops the reset email.
  • Comment form (guests only): every post type except products. Logged-in users are never asked.
  • My Account / checkout login form: the My Account login and the login on the classic checkout page. WooCommerce prints the checkout one only when WooCommerce → Settings → Accounts & Privacy has Enable log-in during checkout or the account creation option During checkout ticked, and only the first adds the “Click here to login” link that opens it. Both are off by default.
  • My Account registration form: shown only when On “My account” page is ticked in the same tab, which is off by default.
  • My Account lost password form: a wrong code blocks the reset email here too.
  • Product review form (guests only): the comment form on products, with its own switch.

What you need

  • WordPress 6.0 or later and PHP 7.4 or later. The plugin header says tested up to WordPress 7.1.
  • PHP GD with FreeType. Without it the plugin switches itself off.
  • WooCommerce is optional and needed only for the four WooCommerce checkboxes. The header says tested up to 11.1. The plugin never reads or writes orders, products or carts.
  • A licence key if you want updates. It is a paid plugin, but the code never checks the licence when it shows or checks a code: without a key it keeps working and only updates are withheld. Activate the key under Plugins → WpExperts Hub Licences.

Step-by-step setup

  1. Download the plugin zip from My Account → Downloads on wpexpertshub.com.
  2. In WordPress, open Plugins → Add Plugin → Upload Plugin, choose the zip, click Install Now, then Activate Plugin.
  3. Open Settings → Protect Login Forms. If a yellow notice says the image library is not available, nothing is protected until your host enables GD with FreeType.
  4. Untick any form you do not want to protect.
  5. Click Save Changes.
  6. Exclude your login, My Account and comment pages from CDN and server caches.
  7. Test it: keep your admin session open in your normal window. In a private window, open your login form and look for “Authenticate yourself, you’re human.” Submit a wrong code on purpose, then log in with the new code on the page that comes back. Repeat for every login form your site uses, including any from a theme or page builder.

What the visitor sees

Under the label “Authenticate yourself, you’re human.” sit a 112 by 44 pixel image of a code (5 characters by default), a text box and the hint “Type the code exactly as shown: capital and small letters are different.”

The match is exact and case sensitive: aB4 is not AB4. The code draws on 32 characters: the capitals A B D E F G H J M N Q R T, the small letters a b d e f g h j n q r t y and the digits 2 to 7. Look-alikes such as I, l, 1, O and 0 are left out. Spaces and invisible characters in the typed code, such as a non-breaking space from a paste, are ignored.

  • Empty box: “Please enter the authentication code shown in the image.”
  • Anything else wrong: “The authentication code entered is invalid or has expired. Please try again.” A wrong, expired or already used code, or a missing token, gets this one message.
  • Where it shows: as a login error on wp-login.php, as a notice on WooCommerce forms, and on comments and reviews as a plain page titled “Comment verification failed” with a Back link.

How the code is made and checked

  • Signed, not stored: the form carries a hidden token made of an expiry time, random characters and a signature built with your site’s nonce key and salt. The answer is worked out from the token when the form comes back, so it is never stored and reaches the browser only as the picture.
  • One use: a code works once, right or wrong, even when many requests carrying it arrive at the same moment. A wrong guess cannot be retried on the same image, and a form submitted twice uses the code up.
  • Expiry: 1 hour on every form except comments and reviews, which get 6 hours so a long comment is not lost.
  • One form each: a login code fails on the registration form. Comments and reviews share one binding, so a code from one passes on the other.
  • What is kept: an anonymous marker row in the options table for each submitted code. Expired markers are cleaned up hourly at most, and deleting the plugin removes the rest. No cookies, IP addresses or names are stored.

On wp-login.php a wrong code replaces the password result without revealing whether the password was right. WordPress treats it as a failed sign-in, so a limiter such as User Security Guard counts it, and a visitor’s mistyped codes count toward its limit. On the WooCommerce login form the code is checked before sign-in, so a wrong code there is not a failed sign-in. On comments the code is checked before the other fields, so a guest who forgot a required field has already used it and must reload the page.

Accessibility and fallback

The text box has a label and is marked required, and the image has the description “Image containing the authentication code to type below”. That tells a screen reader an image is there, not what it says. There is no audio alternative, so a visitor who cannot read the image cannot pass a form that has a code. If that matters for your audience, switch off the forms where it would shut someone out.

If the server cannot draw the image (GD, the bundled font or FreeType is missing), the plugin treats every form as switched off. No code is shown, nothing is checked and your forms keep working. The settings screen shows a yellow notice saying so.

Custom forms carry the opposite risk. A login form from a theme or page builder that posts to wp-login.php without showing the code is refused with “Please enter the authentication code shown in the image.” If that locks you out, rename the wphub-stop-spam folder in /wp-content/plugins/ over FTP, log in, rename it back and switch that form off. Opening the Plugins screen while the folder is renamed makes WordPress deactivate the plugin, so activate it again first.

Caching, CDNs and proxies

A new token and image are made every time a protected form is shown, and the plugin defines DONOTCACHEPAGE, which page-cache plugins that honour it use to skip the page. A CDN or server cache that ignores it can serve an old copy whose code has expired or was already used by an earlier visitor, and visitors get the “invalid or has expired” message. This includes every post or product page that shows the comment or review form to a logged-out visitor; to cache those pages, switch off the comment and review boxes.

The plugin never reads IP addresses, so a reverse proxy, load balancer or Cloudflare does not change how a code is checked. It keeps no session, so servers that share one database and the same NONCE_KEY and NONCE_SALT can check each other’s codes. Changing those constants invalidates codes already shown.

What it does not stop

  • Determined attackers: no image captcha is unbreakable, and OCR, AI or human solving services can get past it.
  • XML-RPC and REST sign-ins: they do not post the log field the login check looks for, so password guessing through them is not checked.
  • Trackbacks and pingbacks: they have no form. Turn them off for new posts under Settings → Discussion if spam arrives that way.
  • WooCommerce checkout accounts: creating an account during checkout is not a separate form and is not checked, and the Cart and Checkout blocks show no code.
  • Other forms: anything that is not one of the eight above, including the screen where a visitor sets a new password after clicking the emailed link and the multisite sign-up screen. A theme or page-builder login form that signs people in without the standard log field is not checked either.
  • Comments added by code: a plugin that inserts comments directly, instead of going through WordPress’s comment submission, is not checked.

Good to know and troubleshooting

  • “Invalid or has expired” on a code that looks right: check capitals and small letters first. Other causes are a form submitted twice, a page open longer than the code lifetime, or a cached copy. Reload the page for a new code.
  • A form shows no code: either WordPress or WooCommerce is not showing that form (see the conditions above), its box is unticked, the visitor is logged in (comment and review forms), or the settings screen shows the yellow image-library notice.
  • Guest comments refused on a theme with its own comment form: the check runs even when the theme does not show the code. Switch the comment and review boxes off, or have the theme show the code through the plugin’s PHP interface.
  • Guest comments through the REST API or XML-RPC fail: WordPress refuses these by default, and the plugin keeps them refused while the comment or review box is on, even if other code allows them, since they cannot show a code.

The full documentation covers the PHP interface for your own forms, the filters for a code’s lifetime and length, the overridable WooCommerce templates, privacy and uninstall.

Links

Plugin page: Protect Login Forms for WordPress & WooCommerce. Settings reference: Protect Login Forms documentation. More tools: Browse all plugins.

Protect Login Forms for WordPress & WooCommerceStop bots and spam on login, sign-up and comment forms with an image code
View plugin →
More tutorialsKeep reading.
How to Send WordPress Email Through SMTP and Keep an Email Log → How to Create Product Collections in WooCommerce → How to Schedule WordPress Backups to Google Drive or Dropbox →
WPExpertsHub

WordPress and WooCommerce plugins, custom development and technical support.

support@wpexpertshub.com

Products

  • All plugins
  • WooCommerce plugins
  • WordPress plugins
  • Free plugins

Services

  • WordPress development
  • WooCommerce development
  • Maintenance & optimization
  • Migration & security
  • API & integrations

Resources

  • My downloads
  • Documentation
  • Blog
  • Plugin support
  • Refund policy

Company

  • Services
  • Contact
  • My account
© 2026 WpExperts Hub. All rights reserved.
  • Privacy Policy
  • Terms of Service
  • Refund Policy