Bots slip through. What’s the plan for addressing improved AI?
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.
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.
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.
Hello @dchacke
In fact, we already have some of those points implemented:
- Time-based checks: already implemented, see
timestamp_enabledoption - Dynamic honeypots: you can configure them via the
honeypotsoption 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.
Any plans for improvements or tips on making it stricter compared to the default config? Recently, bots are overcrowding the app.