Simple CAPTCHA for Python/Pylons

MISCELLANEOUS -️ July 24, 2010

Why

I have a simple contact form on this website that kept getting spammed. A simple captcha at least gives them some work to do. In fact it has greatly reduced the level of spam. I didn't want to use reCAPTCHA because it would make my site dependent on an external service and, by extension, leak information about my visitors.

Features and limitations

  • + Very simple to integrate with any Python web framework. The library is framework neutral. Example provided is for the awesome [http://pylonshq.com/](Pylons web framework.)
  • + Unlike some other solutions, this one does not require storage for temporary images.
  • - Does not prevent replay. I will fix that if it becomes a problem. (Idea: embed date in encrypted string... Expire 1 hour after... or make date part of key... etc)
  • - Generates only a simple image which is trivially defeated with OCR. On the plus side, that also means users will have no trouble with it either!

Requirements

Generic HOWTO

  1. Download and extract the source. (See links at the end of this page)
  2. Open captcha.py and change the key line to 16 random characters and the font line to point to a valid TTF font.
  3. Put the new captcha.py file in a directory somewhere your web application controllers can import them. (In Pylons, this is the lib directory)
  4. Create a responder/controller that responds with content type "image/png" and make it respond with the output of captcha.GenerateImage(id) where ID is passed in the URL.
  5. In the form requiring a CAPTCHA image:

    1. Call captcha.GenerateID() to generate a random captcha ID.
    2. Insert an image of the form:

        <img src="/mycaptcharesponder/%{id}">

      where %{id} gets replaced with the generated ID from above.

    3. Insert a hidden field of the form:

        <input type="hidden" name="fCaptchaH" value="%{id}">
    4. Insert an input field with text asking the user to type in the number shown.
  6. Finally, check the form submission with captcha.Check(userfield, fCaptchaH) where userfield is the text input by the user and fCaptchaH is the value of the hidden field

Job done!

Downloads