millipedia Posted March 22, 2023 Share Posted March 22, 2023 We're building a site that's going to be using the Comments Module and I'm looking at ways to mitigate the amount of spam I'm expecting. Alongside the usual honeypot / Akismet solutions I was thinking of using Cloudflare's Turnstile captcha doodah. I was thinking of either just not rendering the form until the Turnstile challenge was completed or hooking into the Comments module to validate the Turnstile token, or hell, maybe both. Has anyone done something like this already? It's not obvious to me how to hook into a Comment submission - so if anyone can point me in the right direction that would be a good start. Link to comment Share on other sites More sharing options...
elabx Posted March 22, 2023 Share Posted March 22, 2023 I kinda tried this and gave up lol but here's what I found: You'd probably start with the CommentFormCustom class: https://github.com/processwire/processwire/blob/master/wire/modules/Fieldtype/FieldtypeComments/CommentFormCustom.php The first comments have a little bit on how these could be used. I THINK, that something not covered is upadting the processing of the comment, so my guess is that you could implement your own "CommentFormMillipedia" for example, extending CommentForm just like CommentFormCustom, and override the processInput method, so you could process additional stuff, aside from the form fields. Although from reading the code you'd probably have to copy the whole FieldytpeComment module due to the way ComentFormCustom class is loaded. To be honest it was a bit suprised to see the comment form is not built with the Inputfields API! Maybe to allow more simplicity on the rendering? 1 Link to comment Share on other sites More sharing options...
millipedia Posted March 23, 2023 Author Share Posted March 23, 2023 Thanks @elabx(although slightly discouraging that even you gave up...). I think I'm going to switch tack and hook in ProcessPageView::execute to check the token and then just redirect if it fails. I'll let you know how I get on.... 1 Link to comment Share on other sites More sharing options...
millipedia Posted March 23, 2023 Author Share Posted March 23, 2023 OK - this kind of works: In my template I've included the Cloudflare script (and added their end point to the content security policy). Then I'm injecting a placeholder into the form: $comments_form= $page->comments->renderForm(array( 'requireHoneypotField' => 'email2' )); // add a div with class="cf-turnstil" to the form - this gets replaced with a token (after a successful challenge) $cft_tag='<div class="cf-turnstile" data-sitekey="yourturnstilesitekey"></div>'; $comments_form=str_replace("CommentForm' method='post'>","CommentForm' method='post'>$cft_tag", $comments_form); echo $comments_form; Cloudflare replaces that with a token if they think you're not a bot. Then in init.php (not _init.php) I'm hooking into ProcessPageVIew $this->addHookBefore('ProcessPageView::execute', function(HookEvent $event) { if(wire('input')->post('CommentForm_submit')){ // get the Cloudflare token. $cf_token=wire('input')->post('cf-turnstile-response'); // and send it to siteverify $postdata = http_build_query( array( 'secret' => 'yoursupersecretcloudflaresecretkey', 'response' => $cf_token ) ); $opts = array('http' => array( 'method' => 'POST', 'header' => 'Content-Type: application/x-www-form-urlencoded', 'content' => $postdata ) ); $context = stream_context_create($opts); $api_json_response = file_get_contents('https://challenges.cloudflare.com/turnstile/v0/siteverify', false, $context); if($api_json_response ){ // check result and redirect if failed. $result=json_decode($api_json_response,TRUE); if(!($result['success'])){ // die or redirect or whaterver you fancy. // print_r($result); // die("Failed verification."); wire('session')->redirect('/some-help-page-or-something/'); } }else{ // die or redirect or whaterver you fancy. die("No response from verification server."); } } }); If we have a comment that's been submitted then I check the token with Cloudflare. If it fails we can redirect or die or something - it'd be nice to fail a bit more gracefully. No idea how well this will deal with spam and I think I'll need to do some user testing but I think it might be useful. 3 Link to comment Share on other sites More sharing options...
Greg Lumley Posted July 3 Share Posted July 3 Thank you for sharing, how's it working out? Link to comment Share on other sites More sharing options...
millipedia Posted July 3 Author Share Posted July 3 Well it's been trundling along for the last year on the British Record Shop Archive using the above method. We've had a couple of thousand comments ... and I honestly don't remember having a single bit of spam (famous last words there) so I'd say it's been pretty successful. I'm planning to redo the comments forms on the BRSA to allow users to submit images, so I'm probably going to end up with a custom form rather than the above, but it's worked so far. 1 Link to comment Share on other sites More sharing options...
millipedia Posted July 3 Author Share Posted July 3 2 minutes ago, millipedia said: Well it's been trundling along for the last year on the British Record Shop Archive using the above method. We've had a couple of thousand comments ... and I honestly don't remember having a single bit of spam (famous last words there) so I'd say it's been pretty successful. I'm planning to redo the comments forms on the BRSA to allow users to submit images, so I'm probably going to end up with a custom form rather than the above, but it's worked so far. Just reminding myself of what else we did, and there's also some form obfuscation going on. I'm rot13ing the comments form markup (with the injected field above) and then when the user clicks the comment button I'm unobfuscating it and getting Cloudflare to fire it's challenge. I just thought that not having the form visible without some user inaction might fool a couple of bots. Of course now my secret is out .... Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now