invisible_captcha icon indicating copy to clipboard operation
invisible_captcha copied to clipboard

Bots slip through. What’s the plan for addressing improved AI?

Open dchacke opened this issue 2 months ago • 3 comments

I use invisible captcha in a sign-up form:

<%= f.invisible_captcha :username, nonce: true %>

I do not, in fact, let people pick a username, but was hoping it would trick bots.

Some bots still make it past the honeypot, though. I’m guessing they’re becoming smart enough to ignore it.

Any known workarounds? I expect this problem to become more pressing as AI continues to improve in the near future.

dchacke avatar Sep 30 '25 20:09 dchacke

Hello @dchacke 👋🏼

Yes, sure — as AI continues to improve, a lot of things will change in the world 🙂. Our current techniques are still effective against basic bots, but more advanced ones may require additional layers or checks. Some directions could be: more timing checks, randomized honeypots, rate limiting, ... but really happy to discuss any other ideas.

It might also make sense to add some kind of hooks/extension in the gem, so other developers can experiment with their own strategies without adding too much complexity to the core.

markets avatar Sep 30 '25 21:09 markets

Well, if you can’t beat ‘em…

https://chatgpt.com/share/68dc9a6e-dd50-8003-9c88-734ff1bf55c1

[N]o single approach will stop determined bots, but you can layer in additional friction. If you wanted to extend invisible_captcha, here are some ideas:

Time-based checks: Add minimum and maximum form completion times. Bots often submit instantly, or sometimes too slowly.

Dynamic honeypots: Instead of one static hidden field, generate randomized honeypot field names per request, and validate them on submission.

Behavioral checks: Require some basic client-side behavior, e.g. JavaScript-generated token or mouse/keyboard activity indicator. Real users will trigger these naturally, bots might not.

Entropy in field order: Shuffle input field order slightly with CSS positioning. Many bots assume a fixed order.

Hashing or signing fields: Sign form field values server-side and validate them on submit. Prevents bots from fabricating requests without rendering the form.

Progressive friction: If suspicious (too many attempts, IP flagged, missing JS, etc.), fall back to a stronger captcha like reCAPTCHA, puzzle, or email confirmation.

Adaptive honeypots: Add honeypots only when suspicious conditions are met, so bots can’t adapt easily.

Server-side heuristics: Track failed attempts by IP, user-agent, or patterns (e.g. repeated same email format, domains, disposable email services) and throttle or block.

If you were to contribute to the gem itself, the biggest value-adds might be dynamic honeypots, timing checks, and adaptive fallbacks — they’re simple but raise the bar significantly.

dchacke avatar Oct 01 '25 03:10 dchacke

Hello @dchacke

In fact, we already have some of those points implemented:

  • Time-based checks: already implemented, see timestamp_enabled option
  • Dynamic honeypots: you can configure them via the honeypots option or rely on defaults: https://github.com/markets/invisible_captcha/blob/939f9ed7647db51ad01346a459c2fc57711a94db/lib/invisible_captcha.rb#L65-L67
  • Entropy in field order: I think we also have something similar, as we have different rules to hide the honeypot input: https://github.com/markets/invisible_captcha/blob/939f9ed7647db51ad01346a459c2fc57711a94db/lib/invisible_captcha.rb#L73-L79
  • We also have an IP based "spinner" validation

Maybe we can introduce more checks, like an automatic bot detection (by using something like https://github.com/loadkpi/crawler_detect). On the other hand, users can also easily implement throttling by using rack-attack in the app.

markets avatar Oct 06 '25 10:10 markets

Any plans for improvements or tips on making it stricter compared to the default config? Recently, bots are overcrowding the app.

dpashutskii avatar Dec 18 '25 18:12 dpashutskii