@@ -347,6 +347,7 @@ public static function processFormBuilderPage($params)
347347 $ finalize = isset ($ params ["finalize " ]) ? $ params ["finalize " ] : false ;
348348
349349 $ failed_validation = false ;
350+ $ update_successful = true ;
350351 $ validation_error = "" ;
351352 if ($ page_type == "form " ) {
352353 $ tabs = ViewTabs::getViewTabs ($ view_id , true );
@@ -384,29 +385,35 @@ public static function processFormBuilderPage($params)
384385 }
385386 }
386387
387- // TODO. This is insufficient - can be bypassed!
388- $ has_captcha = isset ($ form_data ["g-recaptcha-response " ]) ? true : false ;
388+ // reCAPTCHA just adds a "g-recaptcha-response" key to the POST form values. Looking for that isn't sufficient
389+ // because a hacker could just simulate the request without the property and bypass it. So instead the {{captcha}}
390+ // function makes a note in sessions that the page contains a CAPTCHA - which can't be bypassed
391+ $ has_captcha = isset ($ _SESSION [$ namespace ]["has_captcha " ]) ? $ _SESSION [$ namespace ]["has_captcha " ] : false ;
389392
390393 // the reCAPTCHA can be placed on the form or review page only
391394 if ($ has_captcha && ($ page_type == "form " || $ page_type == "review " )) {
395+ $ recaptcha_error_msg = "• Sorry, you didn't enter the reCAPTCHA correctly. Please try again. " ;
392396
393- // was there a reCAPTCHA response? If so, a recaptcha was just submitted, check it was entered correctly
394- $ resp = $ api ->validateRecaptcha ($ params ["form_data " ]["g-recaptcha-response " ]);
395-
396- if ($ resp ->isSuccess ()) {
397- $ _SESSION [$ namespace ]["passed_captcha " ] = true ;
398- } else {
399- // if the main update was successful, but they failed validation, just display the single "wrong captcha" error
400- if ($ update_successful ) {
401- $ validation_error = "• Sorry, you didn't enter the reCAPTCHA correctly. Please try again. " ;
397+ if (isset ($ params ["form_data " ]["g-recaptcha-response " ])) {
398+ $ resp = $ api ->validateRecaptcha ($ params ["form_data " ]["g-recaptcha-response " ]);
399+ if ($ resp ->isSuccess ()) {
400+ $ _SESSION [$ namespace ]["passed_captcha " ] = true ;
402401 } else {
403- $ br = (!empty ($ validation_error )) ? "<br /> " : "" ;
404- $ validation_error .= $ br . "• Sorry, you didn't enter the reCAPTCHA correctly. Please try again. " ;
402+ // if the main update was successful, but they failed validation, just display the single "wrong captcha" error
403+ if ($ update_successful ) {
404+ $ validation_error = $ recaptcha_error_msg ;
405+ } else {
406+ $ br = (!empty ($ validation_error )) ? "<br /> " : "" ;
407+ $ validation_error .= $ br . $ recaptcha_error_msg ;
408+ }
409+ $ failed_validation = true ;
405410 }
406- $ failed_validation = true ;
407411 }
408412 }
409413
414+ // always reset the has_captcha flag for the next page load
415+ $ _SESSION [$ namespace ]["has_captcha " ] = false ;
416+
410417 // this automatically sends any emails set to the on_submission trigger.
411418 if (!$ failed_validation ) {
412419 if ($ finalize ) {
0 commit comments