Summary: Use captchas to prevent automated systems from modifying pages
Version: 20230227
Prerequisites: pmwiki-2.3.15 or more recent
Status: Stable
Maintainer: Petko
License: GPL2+
Discussion: Captcha-Talk
Users: +9 (View / Edit)

Warning: As of 2023, some OCR software can recognize codes on the Captcha picture created by this recipe. While most generic spambots will fail the captcha, a dedicated attacker could automate the code recovery, and you shouldn't rely on this for security against brute force attacks. We need to explore and review other options. ReviewMe. --Petko

Questions answered by this recipe


This recipe provides a captcha capability that can be embedded into forms used by PmWiki. The captcha recipe works by displaying a random sequence of digits as part of an input form, and prompting the visitor to enter the digits into a text field in the form. Here is an example:

(:input form action={*$PageUrl} method=post:)
Enter value: {$Captcha} (:input captcha:)
(:input submit:)
(:input end:)

(:if captcha:)
%green%Captcha succeeded%%
%red%Captcha failed%%

Enter value: Captcha

Captcha failed

On systems that support it, the digits will be displayed as a distorted graphic image to increase the difficulty of an automated system determining the correct sequence. For PHP sites that don't have image manipulation support, the digits are displayed as plain text (this will still defeat a substantial number of robots).


To use this recipe in a typical setup:

  1. download captcha.phpΔ, copy it into the cookbook/ directory, and add one of the following two lines to a local customization file, such as 'local/config.php':
    if (!CondAuth($pagename,'edit')) $EnablePostCaptchaRequired = 1;
    Note: The condition will allow users with Edit permissions to by-pass the captcha. If you want all users to have to enter the captcha omit the condition and simply use. For more information refer to selective enabling.
    $EnablePostCaptchaRequired = 1;
  2. To require a captcha in order to edit a page, add the following markup to an appropriate place in the Site.EditForm page (or wherever edit forms are being held): Enter value: {$Captcha} (:input captcha:)
  3. To enable image captchas rather than the text version you may need to add this to config.php:

Now, any request (even if you are authenticated) to save a page that doesn't contain a valid captcha code will be denied (with an opportunity to re-submit the request with the correct code).

Selectively Enable Captcha

by overtones99

Enabling captcha as described in the section made it so that I couldn't edit any of my pages without having to include a captcha code input on the edit form, and filling it out every time (lame!). There are various approaches to selectively enabling captcha.

Turn off captcha if you have edit permission

by Hans

Turns off captcha if you're logged in and have edit permissions:

$EnablePostCaptchaRequired = 1;
if (CondAuth($pagename,'edit'))
   $EnablePostCaptchaRequired = 0;

Enable for specific pages

by Randy

Enables for specific named pages, if you have edit permissions.

if (($pagename=='MyPage1' || ($pagename=='MyPage2')) && $action != 'edit')
   $EnablePostCaptchaRequired = true;

Disable captcha in later processing

by ari October 29, 2008, at 12:21 PM EDT

Turn off captcha completely for edit (if you only want it to work for commentboxes, for example), after captcha is already enabled, add this code within appropriate conditional statements:

$EditFunctions = array_diff($EditFunctions, array('RequireCaptcha') );

Loading a new captcha image

by Ian MacGregor

If your visitors are having a difficult time reading the captcha, you may want to add text somewhere in the page which gives the visitor a good method for "re-generating" the captcha. I added this to my Site.EditForm:

"If the captcha is too difficult to read, click the Send button and try again."

as that will re-generate the captcha while preserving the text the visitor might have already entered into the form.

Displaying image captcha, not a text captcha

by Ian MacGregor

If you're finding that the captcha is displayed as text instead of an image, you can try adding this to the local/config.php:


This seemed to force the captcha to display as an image instead of text on my server.

Integration with Mailform2

by JamesM?

To integrate with Cookbook.Mailform2, add the following line *after* you load the captcha.php, and before loading mailform2.php, in 'local/config.php'. Then ensure that any mail form you use has the captcha code shown above (i.e. "Enter value: {$Captcha} (:input captcha:)").

$Mailform2Disabled = $Mailform2Disabled || !IsCaptcha();

Release Notes (by Petko)

  • 20230227 Added (:input captcha1 value="" placeholder="$[Type code]" required=required:) that includes the image and the text field. If $EnableCaptchaSession is set, and a user has already replied correctly once, this will show nothing.
  • 20221123 Fixes for PHP 8.2.
  • 20210822 Fix warnings reported in PHP 8.
  • 20180305 Fix 2 warnings in PHP7 error logs, one reported by Johan Bengtsson.
  • 20170623 Validate HTML for Captcha image, add $CaptchaImageCSS.
  • 20170619 Add $EnableCaptchaImageDataURI, set to 1 to embed the picture directly into the page (captcha will only appear for standard browsers and MSIE8+).
  • 20170609 Add default class=inputbox like other text fields; change rand with mt_rand.
  • 20151002 Disable autocomplete suggestions.



See discussion at Captcha-Talk

User notes : If you use, used or reviewed this recipe, you can add your name. These statistics appear in the Cookbook listings and will help newcomers browsing through the wiki.