Skip to content

Commit 9b0fc70

Browse files
authored
Fix logic for recaptcha v3 on error states (#698)
Certain error states in the recaptcha v3 API do not return a score. However, we were defaulting to a "good" score and therefore the errors were being let through. This first checks if the request was successful. If so, it then compares the score. Fallbacks have also been changed from "good" states to sentinel values, which should be helpful for debugging in production.
1 parent 02e829d commit 9b0fc70

2 files changed

Lines changed: 11 additions & 7 deletions

File tree

coderedcms/models/page_models.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1640,7 +1640,10 @@ def contains_spam(self, request) -> bool:
16401640
utils.get_ip(request),
16411641
)
16421642
# Score ranges from 0 (likely spam) to 1 (likely good).
1643-
return rr.score < ls.recaptcha_threshold
1643+
if rr.success and rr.score >= 0:
1644+
return rr.score < ls.recaptcha_threshold
1645+
else:
1646+
return True
16441647
elif ls.spam_service == ls.SpamService.RECAPTCHA_V2:
16451648
rr = verify_response(
16461649
request.POST.get("g-recaptcha-response", ""),

coderedcms/recaptcha.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111

1212
class RecaptchaResponse(typing.NamedTuple):
13-
success: bool
13+
success: typing.Union[bool, None]
1414
score: float
1515
error_codes: typing.List[str]
1616
original_data: typing.Dict[str, typing.Any]
@@ -43,11 +43,12 @@ def verify_response(recaptcha_response: str, secret_key: str, remoteip: str):
4343
response = urlopen(request)
4444
data = json.loads(response.read().decode("utf8"))
4545
response.close()
46-
logger.info(f"reCAPTCHA response: {data}")
47-
# Default to good (likely not spam) values if they are not present.
48-
return RecaptchaResponse(
49-
success=data.get("success", True),
50-
score=data.get("score", 1.0),
46+
# Default to sentinel values if not provided by Google.
47+
rr = RecaptchaResponse(
48+
success=data.get("success", None),
49+
score=data.get("score", -1.0),
5150
error_codes=data.get("error-codes", []),
5251
original_data=data,
5352
)
53+
logger.info(f"reCAPTCHA response: {rr}")
54+
return rr

0 commit comments

Comments
 (0)