zendesk / kamcaptcha

A captcha plugin for Rails
Apache License 2.0
63 stars 12 forks source link

Do yourself a favor and don't use this #4

Open outerim opened 12 years ago

outerim commented 12 years ago

This captcha implementation suffers from a very simple replay attack. The plugin essentially adds a captcha image, a hidden/encrypted field, and a text input for the user to supply the captcha value.

Doesn't matter how you protect your keys, how you generate the images etc. You essentially allow the user to pick the image they want to supply the captcha answer to by putting the encrypted text in the form. In order to exploit any form using this plugin all you have to do is this:

You can now refresh the page, replace the value of the hidden field with the previous one and supply your known good answer repeat as many times as desired. It doesn't matter what image is displayed all the controller helper validates is that the text you supply matches the encrypted text you also supplied. D'oh!

A simple solution is to store the encrypted validation field in the session rather than using a hidden input. Doing that makes this as strong as the captcha image that's generated. Which admittedly isn't very good but it's better than nothing I suppose.

lentschi commented 11 years ago

Hey outerim,

I don't know if this was implemented when you tried out the plugin - but with the current version I was able to prevent replay attacks by adding the following code to the kamcaptcha initializer:

Kamcaptcha::Token.store = lambda do |token| 
  session[:kamcaptcha_token] = token
end

Kamcaptcha::Token.lookup = lambda do 
  session[:kamcaptcha_token]
end

I believe the developers didn't put this in by default, to leave the gem as independent from rails as possible. (Of course fetching the token from the params is rails dependent too, but it can be easily changed to another algorithm.)

Cheers, lentschi

outerim commented 11 years ago

Sure it just seemed like a rather glaring omission. The documentation in the README doesn't touch on this issue. Anyone who unwittingly follows it is left with forms that are no more protected from bots than any other bare form lying around. Your solution, while effective, (and accomplishing exactly what I proposed) doesn't change the fact that the library as implemented encourages a very weak approach.

lentschi commented 11 years ago

Yeah, that's true - a hint in the README would be nice. (Actually I only stumbled across your issue report, because I googled 'kamcaptcha session' after viewing the source and realizing that this weakness existed.)