Browse Source

fix captcha v3 issue

Jason Rivard 4 years ago
parent
commit
f457cd4de3

+ 59 - 16
server/src/main/java/password/pwm/util/CaptchaUtility.java

@@ -70,13 +70,45 @@ public class CaptchaUtility
 
 
     public enum CaptchaMode
     public enum CaptchaMode
     {
     {
-        V3,
-        V3_INVISIBLE,
+        V2( null ),
+        V2_INVISIBLE( null ),
+
+        // v3 versions deprecated since implementation is actually V2 only.
+        V3( V2 ),
+        V3_INVISIBLE( V2_INVISIBLE ),;
+
+        private final CaptchaMode replacement;
+
+        CaptchaMode( final CaptchaMode replacement )
+        {
+            this.replacement = replacement;
+        }
+
+        public CaptchaMode getReplacement()
+        {
+            return replacement;
+        }
+
+        boolean isDeprecated()
+        {
+            return replacement != null;
+        }
     }
     }
 
 
     public static CaptchaMode readCaptchaMode( final PwmRequest pwmRequest )
     public static CaptchaMode readCaptchaMode( final PwmRequest pwmRequest )
     {
     {
-        return pwmRequest.getConfig().readSettingAsEnum( PwmSetting.CAPTCHA_RECAPTCHA_MODE, CaptchaMode.class );
+        final CaptchaMode captchaMode = pwmRequest.getConfig().readSettingAsEnum( PwmSetting.CAPTCHA_RECAPTCHA_MODE, CaptchaMode.class );
+        if ( captchaMode == null )
+        {
+            return CaptchaMode.V2;
+        }
+
+        if ( captchaMode.isDeprecated() )
+        {
+            return captchaMode.getReplacement();
+        }
+
+        return captchaMode;
     }
     }
 
 
     /**
     /**
@@ -146,26 +178,37 @@ public class CaptchaUtility
 
 
             final JsonElement responseJson = new JsonParser().parse( clientResponse.getBody() );
             final JsonElement responseJson = new JsonParser().parse( clientResponse.getBody() );
             final JsonObject topObject = responseJson.getAsJsonObject();
             final JsonObject topObject = responseJson.getAsJsonObject();
-            if ( topObject != null && topObject.has( "success" ) )
+            if ( topObject != null )
             {
             {
-                final boolean success = topObject.get( "success" ).getAsBoolean();
-                if ( success )
+                if ( topObject.has( "score" ) )
                 {
                 {
-                    writeCaptchaSkipCookie( pwmRequest );
-                    LOGGER.trace( pwmRequest, () -> "captcha verification passed" );
-                    StatisticsManager.incrementStat( pwmRequest, Statistic.CAPTCHA_SUCCESSES );
-                    return true;
+                    final String errorMsg = "captcha response contains 'score' attribute, indicating captcha setting key is not expected Version 2 key type";
+                    LOGGER.error( () -> errorMsg );
+                    final ErrorInformation errorInfo = new ErrorInformation( PwmError.ERROR_CAPTCHA_API_ERROR, errorMsg );
+                    throw new PwmUnrecoverableException( errorInfo );
                 }
                 }
 
 
-                if ( topObject.has( "error-codes" ) )
+                if ( topObject.has( "success" ) )
                 {
                 {
-                    final List<String> errorCodes = new ArrayList<>();
-                    for ( final JsonElement element : topObject.get( "error-codes" ).getAsJsonArray() )
+                    final boolean success = topObject.get( "success" ).getAsBoolean();
+                    if ( success )
+                    {
+                        writeCaptchaSkipCookie( pwmRequest );
+                        LOGGER.trace( pwmRequest, () -> "captcha verification passed" );
+                        StatisticsManager.incrementStat( pwmRequest, Statistic.CAPTCHA_SUCCESSES );
+                        return true;
+                    }
+
+                    if ( topObject.has( "error-codes" ) )
                     {
                     {
-                        final String errorCode = element.getAsString();
-                        errorCodes.add( errorCode );
+                        final List<String> errorCodes = new ArrayList<>();
+                        for ( final JsonElement element : topObject.get( "error-codes" ).getAsJsonArray() )
+                        {
+                            final String errorCode = element.getAsString();
+                            errorCodes.add( errorCode );
+                        }
+                        LOGGER.debug( pwmRequest, () -> "recaptcha error codes: " + JsonUtil.serializeCollection( errorCodes ) );
                     }
                     }
-                    LOGGER.debug( pwmRequest, () -> "recaptcha error codes: " + JsonUtil.serializeCollection( errorCodes ) );
                 }
                 }
             }
             }
         }
         }

+ 3 - 3
server/src/main/resources/password/pwm/config/PwmSetting.xml

@@ -1504,11 +1504,11 @@
     </setting>
     </setting>
     <setting hidden="false" key="captcha.recaptcha.mode" level="2">
     <setting hidden="false" key="captcha.recaptcha.mode" level="2">
         <default>
         <default>
-            <value>V3</value>
+            <value>V2</value>
         </default>
         </default>
         <options>
         <options>
-            <option value="V3">reCaptcha Version 3</option>
-            <option value="V3_INVISIBLE">reCaptcha Version 3 - Invisible</option>
+            <option value="V2">reCaptcha Version 2</option>
+            <option value="V2_INVISIBLE">reCaptcha Version 2 - Invisible</option>
         </options>
         </options>
     </setting>
     </setting>
     <setting hidden="false" key="security.formNonce.enable" level="2" required="true">
     <setting hidden="false" key="security.formNonce.enable" level="2" required="true">

+ 2 - 2
webapp/src/main/webapp/WEB-INF/jsp/fragment/captcha-embed.jsp

@@ -38,7 +38,7 @@
     <span><pwm:display key="Display_JavascriptRequired"/></span>
     <span><pwm:display key="Display_JavascriptRequired"/></span>
     <a href="<pwm:context/>"><pwm:display key="Title_MainPage"/></a>
     <a href="<pwm:context/>"><pwm:display key="Title_MainPage"/></a>
 </noscript>
 </noscript>
-<% if ( captchaMode == CaptchaUtility.CaptchaMode.V3 ) { %>
+<% if ( captchaMode == CaptchaUtility.CaptchaMode.V2 ) { %>
 <%-- begin reCaptcha section (http://code.google.com/apis/recaptcha/docs/display.html) --%>
 <%-- begin reCaptcha section (http://code.google.com/apis/recaptcha/docs/display.html) --%>
 <pwm:script>
 <pwm:script>
     <script type="text/javascript">
     <script type="text/javascript">
@@ -60,7 +60,7 @@
 </pwm:script>
 </pwm:script>
 <script nonce="<pwm:value name="<%=PwmValue.cspNonce%>"/>" src="<%=(String)JspUtility.getAttribute(pageContext,PwmRequestAttribute.CaptchaClientUrl)%>?onload=onloadCallback&render=explicit" defer async></script>
 <script nonce="<pwm:value name="<%=PwmValue.cspNonce%>"/>" src="<%=(String)JspUtility.getAttribute(pageContext,PwmRequestAttribute.CaptchaClientUrl)%>?onload=onloadCallback&render=explicit" defer async></script>
 <% } %>
 <% } %>
-<% if ( captchaMode == CaptchaUtility.CaptchaMode.V3_INVISIBLE ) { %>
+<% if ( captchaMode == CaptchaUtility.CaptchaMode.V2_INVISIBLE ) { %>
 <!-- captcha v3-invisible 1.0 -->
 <!-- captcha v3-invisible 1.0 -->
 <input type="hidden" name="<%=CaptchaUtility.PARAM_RECAPTCHA_FORM_NAME%>" id="<%=CaptchaUtility.PARAM_RECAPTCHA_FORM_NAME%>"/>
 <input type="hidden" name="<%=CaptchaUtility.PARAM_RECAPTCHA_FORM_NAME%>" id="<%=CaptchaUtility.PARAM_RECAPTCHA_FORM_NAME%>"/>
 <pwm:script>
 <pwm:script>