{"id":589,"date":"2018-11-03T08:21:34","date_gmt":"2018-11-03T12:21:34","guid":{"rendered":"http:\/\/salzlechner.com\/dev\/?p=589"},"modified":"2018-11-03T08:21:34","modified_gmt":"2018-11-03T12:21:34","slug":"webapp-security-series-recaptcha","status":"publish","type":"post","link":"http:\/\/salzlechner.com\/dev\/2018\/11\/03\/webapp-security-series-recaptcha\/","title":{"rendered":"WebApp Security Series &#8211; reCaptcha"},"content":{"rendered":"<p>In this first post on security with DataFlex WebApp we are looking at hardening the login of our webapp using Googles reCaptcha technology.<\/p>\n<p>Googles reCaptcha is a free service that allows us to tell humans apart from bots and use that information to keep our site more secure.<\/p>\n<p>We are going to implement both reCaptcha V2, the more commonly known reCaptcha with the &#8216;I am not a robot&#8217; checkbox as well as reCaptcha V3.<\/p>\n<p>reCaptcha V3 is completely invisible to the user and returns a score that can be used to control the use of additional security features such as Two Factor Authentication<\/p>\n<p>To use Googles reCaptcha technology we will use the reCaptcha web control from <a href=\"http:\/\/www.starzen.com\">StarZen Technologies<\/a>. It is a simple wrapper control that allows use to easily incorporate the reCaptcha technology into our webapp<\/p>\n<h2>Add StarZen&#8217;s reCaptcha control<\/h2>\n<p>To add the reCaptcha control to the webapp we have to copy the javascript files to our AppHtml folder. We also have to add the package files for the control to our source folders.<\/p>\n<p>In addition we have to reference these files in our index.html file as follows<\/p>\n<pre class=\"lang:default decode:true\">&lt;!-- StarZen reCaptcha V2 --&gt;\t\r\n&lt;link rel=\"stylesheet\" type=\"text\/css\" href=\"StarZen\/szdfreCaptchaV2.css\"&gt;\r\n&lt;script src=\"StarZen\/szdfreCaptchaV2.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;\r\n\r\n&lt;!-- StarZen reCaptcha V3 --&gt;\t\r\n&lt;script src='https:\/\/www.google.com\/recaptcha\/api.js?render=6LdHBGMUAAAAADKVo1rguQeHBAn-iZ1ObeIOvlog'&gt;&lt;\/script&gt;\r\n&lt;link rel=\"stylesheet\" type=\"text\/css\" href=\"StarZen\/szdfreCaptchaV3Button.css\"&gt;\r\n&lt;script src=\"StarZen\/szdfreCaptchaV3Button.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;<\/pre>\n<p>The Google reCaptcha service requires us to register and then use a sitekey and a secret phrase. The best way to supply these values to the control is to build a subclass<\/p>\n<p>the code for the reCaptcha V2 class is as follows<\/p>\n<pre class=\"lang:default decode:true\">Class cMyRecaptchaV2 is a cszreCaptchaV2\r\n    Procedure Construct_Object\r\n        Forward Send Construct_Object\r\n\r\n        Set psCaptchaSiteKey to \"YOUR RECAPTCHA SITE KEY\"\r\n        Set psCaptchaSecret to \"YOUR RECAPTCHA SECRET\"\r\n    End_Procedure\r\nEnd_Class<\/pre>\n<p>A Similar class is needed for the V3 reCaptcha button class<\/p>\n<pre class=\"lang:default decode:true\">Class cMyreCaptchaV3Button is a cszreCaptchaV3Button\r\n    Procedure Construct_Object\r\n        Forward Send Construct_Object\r\n\r\n        Set psCaptchaSiteKey to \"YOUR RECAPTCHA V3 SITEKEY\"\r\n        Set psCaptchaSecret to \"YOUR RECPATCHA V3 SECRET\"   \r\n    End_Procedure\r\nEnd_CLass\r\n<\/pre>\n<p>We also want settings to control the use of the reCaptcha control in our application so we will add a few properties to our webapp object<\/p>\n<pre class=\"lang:default decode:true \">\/\/ Recaptcha Settings\r\n\r\n\/\/ Use Recaptcha\r\nProperty Boolean pbUseReCaptcha True\r\n\/\/ Version of recaptcha (V2, V3)\r\nProperty String  psUseCaptchaVersion \"V2\"<\/pre>\n<p>First we add the\u00a0<em>pbUseReCaptcha<\/em> property. Setting it to true will enable reCaptcha while setting it to false will completely disable it.<\/p>\n<p>We also add the\u00a0<em>psUseCaptchaVersion<\/em> property that will allow us to select the version of Recaptcha to use. Currently either &#8220;V2&#8221; or &#8220;V3&#8221;<\/p>\n<p>Now on to the login screen to add the reCaptcha control and use it<\/p>\n<p>After adding a use statement at the top for our reCaptcha V2 class we will add a reCaptcha V2 object just before the login button<\/p>\n<pre class=\"lang:default decode:true\">Object oRecaptchaV2 is a cMyRecaptchaV2\r\n    Set piColumnSpan to 10\r\n    Set piColumnIndex to 1\r\nEnd_Object<\/pre>\n<p>To implement the switch to turn reCaptcha functionality on and off we modify the OnLoad procedure as follows<\/p>\n<pre class=\"lang:default decode:true\">Procedure OnLoad\r\n    Forward Send OnLoad\r\n    Send HideHeader to ghoWebApp\r\n    WebSet psCSSClass of ghoWebApp to \"LoginBackground\"\r\n        \r\n    If (pbUseReCaptcha(ghoWebApp)) Begin\r\n        \/\/ reCaptcha enabled\r\n        Set pbRender of oRecaptchaV2 to True\r\n    End\r\n    Else Begin\r\n        \/\/ reCaptcha disabled\r\n        Set pbRender of oRecaptchaV2 to False  \r\n    End\r\nEnd_Procedure\r\n<\/pre>\n<p>Based on the\u00a0<em>pbUseRecaptcha<\/em> property we either render or hide the reCaptcha V2 control<\/p>\n<p>to use the reCaptcha V2 we need to modify the login buttons OnClick method as follows<\/p>\n<pre class=\"lang:default decode:true \">Procedure OnClick\r\n    If (pbUseReCaptcha(oWebApp(Self))) Begin\r\n        \/\/ verify captcha token with Google\r\n        Send VerifyToken to oRecaptchaV2\r\n                \r\n        If (pbCaptchaResponse_Success(oRecaptchaV2(Self))) Begin\r\n            \/\/ ok\r\n            Send DoLogin \r\n        End\r\n        Else Begin\r\n            \/\/ failed\r\n            Send ShowInfoBox \"Please check the I am not a robot checkbox\"\r\n            Procedure_Return\r\n        End\r\n                \r\n    End\r\n    Else Begin\r\n        Send DoLogin \r\n    End\r\nEnd_Procedure<\/pre>\n<p>when the login button is clicked we call the\u00a0<em>VerifyToken<\/em> method of the reCaptcha control. This will validate our reCaptcha token with google.<\/p>\n<p>if the validation is ok we will simply call the DoLogin method. If the validation fails we will show a message box to the user alerting them to check the &#8216;I am not a robot&#8217; checkbox.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-591\" src=\"http:\/\/salzlechner.com\/dev\/wp-content\/uploads\/sites\/2\/2018\/11\/loginv2.png\" alt=\"\" width=\"284\" height=\"321\" srcset=\"http:\/\/salzlechner.com\/dev\/wp-content\/uploads\/sites\/2\/2018\/11\/loginv2.png 638w, http:\/\/salzlechner.com\/dev\/wp-content\/uploads\/sites\/2\/2018\/11\/loginv2-265x300.png 265w\" sizes=\"(max-width: 284px) 100vw, 284px\" \/><\/p>\n<h2>reCaptcha V3<\/h2>\n<p>The recaptcha V2 service requires a visual element the user has to interact with. The new reCaptcha V3 service does not need any interaction with the user at all. It is fully transparent to the end user<\/p>\n<p>The reCaptcha V3 control returns a score between 0.0 and 1.0, 1 being most likely to be human and 0 being most likely a bot.<\/p>\n<p>We wrapped the reCaptcha V3 functionality into a button class for WebApp making it very easy to be added to for example a login page by replacing the login button<\/p>\n<p>Because we want to be able to switch reCaptcha versions we will add the V3 login button and control the use with our properties<\/p>\n<p>after adding a use statement for our reCaptcha V3 class we created earlier we can add the following button right after the existing login button<\/p>\n<pre class=\"lang:default decode:true \">Object oLoginButtonreCaptchaV3 is a cMyreCaptchaV3Button\r\n    Set pbShowLabel to False\r\n    Set psCaption to \"Login\"\r\n    Set pbServerOnClick to True\r\n    Set piColumnSpan to 10\r\n    Set piColumnIndex to 1\r\n                    \r\n    Set psCaptchaAction to \"Login\"\r\n                                \r\n    Procedure OnCaptchaVerified Boolean bSuccess Number nScore\r\n        If (bSuccess) Begin\r\n                \r\n        End\r\n        Else Begin\r\n            Send ShowInfoBox \"Login Failed - reCaptcha\"\r\n        End\r\n    End_Procedure\r\n\t           \r\nEnd_Object<\/pre>\n<p>this will add another login button to our login screen. Instead of a regular <em>OnClick<\/em> procedure this control as a <em>OnCaptchaVerified<\/em> event that fires when the captcha token us verified after the user clicks the button.<\/p>\n<p>The event has two parameters a boolean indicating success and a number containing the reCaptcha score. The score ranges from 0.0 to 1.0 with 1.0 showing a strong indication of the user being human while a score of 0 showing a strong indication of the user being a bot.<\/p>\n<p>The application can then take steps based on these scores. For this first example we will simply only allow login with scores above a certain number. We will add a property do define that value as well<\/p>\n<p>So lets add our property to our webapp object<\/p>\n<pre class=\"lang:default decode:true \">\/\/ Minimum score required for login\r\nProperty Number  pnMinimumCaptchaScoreForLogin 0.7\r\n<\/pre>\n<p>and then in our <em>OnCaptchVerified<\/em> event we will use that value<\/p>\n<pre class=\"lang:default decode:true \">Procedure OnCaptchaVerified Boolean bSuccess Number nScore\r\n    If (bSuccess) Begin\r\n        If (nScore &gt;= pnMinimumCaptchaScoreForLogin(Self)) Begin\r\n            Send DoLogin\r\n        End\r\n        Else Begin\r\n            Send ShowInfoBox \"Login Failed - reCaptcha Score\"\r\n        End\r\n    End\r\n    Else Begin\r\n        Send ShowInfoBox \"Login Failed - reCaptcha\"\r\n    End\r\nEnd_Procedure\r\n<\/pre>\n<p>This code will now check the score and if the score is at least the score in our setting will allow the login otherwise will show an error to the user<\/p>\n<p>In our next installment to this series we will look at using the score from the recaptcha service to control the use of Two Factor Authentication.<\/p>\n\n\t\t<div class='author-shortcodes'>\n\t\t\t<div class='author-inner'>\n\t\t\t\t<div class='author-image'>\n\t\t\t<img src='http:\/\/salzlechner.com\/dev\/wp-content\/uploads\/sites\/2\/2016\/02\/mike5crop-566174_60x60.jpg' alt='' \/>\n\t\t\t<div class='author-overlay'><\/div>\n\t\t<\/div> \n\t\t<div class='author-info'>\n\t\t\tMichael Salzlechner is the CEO of StarZen Technologies, Inc.<\/p>\n<p>He was part of the Windows Team at Data Access Worldwide that created the DataFlex for Windows Product before joining\u00a0<a href=\"http:\/\/starzen.com\">StarZen Technologies<\/a>. StarZen Technologies provides consulting services as well as custom Application development and third party products specifically for DataFlex developers<\/p>\n\t\t<\/div>\n\t\t\t<\/div>\n\t\t<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this first post on security with DataFlex WebApp we are looking at hardening the login of our webapp using Googles reCaptcha technology. Googles reCaptcha is a free service that allows us to tell humans apart from bots and use that information to keep our site more secure. We are going to implement both reCaptcha [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","ngg_post_thumbnail":0,"footnotes":""},"categories":[27],"tags":[],"class_list":["post-589","post","type-post","status-publish","format-standard","hentry","category-dataflex-webapp"],"_links":{"self":[{"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/posts\/589","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/comments?post=589"}],"version-history":[{"count":3,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/posts\/589\/revisions"}],"predecessor-version":[{"id":593,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/posts\/589\/revisions\/593"}],"wp:attachment":[{"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/media?parent=589"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/categories?post=589"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/tags?post=589"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}