{"record":{"id":"72795f35a843eb79","repo":"wuyouzhuguli/SpringAll","slug":"error-72795f","errorCode":null,"errorMessage":"验证码不正确！","messagePattern":"验证码不正确！","errorType":"validation","errorClass":"ValidateCodeException","httpStatus":null,"severity":"error","filePath":"38.Spring-Security-SmsCode/src/main/java/cc/mrbird/validate/smscode/SmsCodeFilter.java","lineNumber":61,"sourceCode":"\n    private void validateCode(ServletWebRequest servletWebRequest) throws ServletRequestBindingException {\n        String smsCodeInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), \"smsCode\");\n        String mobileInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), \"smsCode\");\n\n        SmsCode codeInSession = (SmsCode) sessionStrategy.getAttribute(servletWebRequest, ValidateController.SESSION_KEY_SMS_CODE + mobileInRequest);\n\n        if (StringUtils.isBlank(smsCodeInRequest)) {\n            throw new ValidateCodeException(\"验证码不能为空！\");\n        }\n        if (codeInSession == null) {\n            throw new ValidateCodeException(\"验证码不存在！\");\n        }\n        if (codeInSession.isExpire()) {\n            sessionStrategy.removeAttribute(servletWebRequest, ValidateController.SESSION_KEY_IMAGE_CODE);\n            throw new ValidateCodeException(\"验证码已过期！\");\n        }\n        if (!StringUtils.equalsIgnoreCase(codeInSession.getCode(), smsCodeInRequest)) {\n            throw new ValidateCodeException(\"验证码不正确！\");\n        }\n        sessionStrategy.removeAttribute(servletWebRequest, ValidateController.SESSION_KEY_IMAGE_CODE);\n\n    }\n}","sourceCodeStart":43,"sourceCodeEnd":66,"githubUrl":"https://github.com/wuyouzhuguli/SpringAll/blob/614d2578d9495acf53cc02f2dee9c6131cc5e51a/38.Spring-Security-SmsCode/src/main/java/cc/mrbird/validate/smscode/SmsCodeFilter.java#L43-L66","documentation":"ValidateCodeException thrown by SmsCodeFilter.validateCode() when the submitted smsCode does not equal the session code (case-insensitive). NOTE: the success-cleanup path on line 63 has the same copy-paste defect as the expiry path - it removes SESSION_KEY_IMAGE_CODE instead of SESSION_KEY_SMS_CODE + mobileInRequest, so a successful match corrupts the image-captcha session attribute and leaves the consumed SMS code in the session (replay risk). Reachable correctly only after the line-46 mobile bug is fixed.","triggerScenarios":"POST to /login/mobile with a present, non-expired smsCode whose value differs from the generated SMS code; or, after fixing line 46, any genuine mismatch.","commonSituations":"User mistyped the SMS code; code regenerated but old one typed; the success path clears the wrong attribute (line 63 bug) enabling SMS-code reuse; line-46 bug means the compared session code is for the wrong key.","solutions":["Fix line 63 to remove ValidateController.SESSION_KEY_SMS_CODE + mobileInRequest on success.","Also fix line 46 so mobileInRequest is read from the 'mobile' parameter.","Have the user re-enter the SMS code exactly, ignoring case.","Regenerate the SMS code if the user is unsure."],"exampleFix":"// before (line 63)\nsessionStrategy.removeAttribute(servletWebRequest, ValidateController.SESSION_KEY_IMAGE_CODE);\n\n// after\nsessionStrategy.removeAttribute(servletWebRequest, ValidateController.SESSION_KEY_SMS_CODE + mobileInRequest);","handlingStrategy":"validation","validationCode":"// normalize user input before submit\nform.smsCode.value = form.smsCode.value.trim();\nif (!form.smsCode.value) { showError('请输入短信验证码'); return; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Fix SmsCodeFilter line 63 to remove SESSION_KEY_SMS_CODE + mobileInRequest on success, preventing SMS-code replay.","Also fix line 46 so the session key is built from the real mobile.","Have the user re-enter the SMS code exactly if it is rejected."],"tags":["spring-security","sms-code","captcha","input-mismatch","bug"],"backgroundTag":null,"analyzedSha":"614d2578d9495acf53cc02f2dee9c6131cc5e51a","analyzedAt":"2026-08-14T04:40:03.488Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}