django-simple-captcha
django-simple-captcha copied to clipboard
BaseCaptchaTextInput should set autocomplete=off on the hashkey HiddenInput
In Firefox, if you fetch a new CAPTCHA via Ajax and change the image src and hashkey values with JavaScript, the new hashkey is remembered between page reloads. However, each time the page is reloaded, a new CAPTCHA image is provided. The result is that the CAPTCHA is impossible to solve since the image received from the server doesn't correspond to the hashkey in the DOM. The autofill happens because autocomplete="off" is not set on the hidden hashkey input. ~~The behavior of Firefox does seem quite odd since values written to the visible input box are not preserved. Only the value set with JavaScript is preserved between reloads.~~ (EDIT: Ah, autocomplete=off is set on the visible input field so of course that's not preserved.) I also tested with Chromium/Chrome but the issue doesn't manifest itself there.
Anyway, my workaround for now is to define a new widget class for the CaptchaField which sets autocomplete=off for all of the CAPTCHA fields:
class CustomCaptchaTextInput(CaptchaTextInput):
def __init__(self, *args, **kwargs):
if not "attrs" in kwargs:
kwargs["attrs"] = {}
kwargs["attrs"].update({"autocomplete": "off"})
super().__init__(*args, **kwargs)
How to reproduce:
- Use the following Django source files
views.py
def test(request):
ctx = { "form": TestForm() }
return HttpResponse(render(request, 'test.html', ctx))
forms.py
class TestForm(forms.Form):
captcha = CaptchaField()
test.html
<head>
<script>
document.addEventListener("DOMContentLoaded", () => {
document.querySelector("#reset").addEventListener("click", async () => {
document.querySelector("#id_captcha_0").value = "THIS IS AUTOFILLED"
});
});
</script>
</head>
<body>
<form action=".">
{% csrf_token %}
{{form.captcha}}
<button id="reset" type="button">Reset</button>
</button>
</body>
- Open the page with Firefox. I used version 78.10.0esr.
- Open the DOM inspector and confirm that the CAPTCHA image src and the hidden hashkey input value belong to the same CAPTCHA.
- Click the Reset button. The hashkey should change to "THIS IS AUTOFILLED".
- Reload the page eg. with F5.
- Confirm that the CAPTCHA image src has changed to a new image but the hidden hashkey input value is still "THIS IS AUTOFILLED". This would cause subsequent CAPTCHA validations to always fail.
Good catch! Would you mind submitting a quick PR that fixes this? :pray:
Sure! I'll look into the PR soon.
Hey @eerotal I noticed you never ended up submitting a PR (I created one off of your branch). Do you think it's ready to be merged? Looks good me...
Sorry, I have totally forgot this issue. I think I planned to improve the tests further, but I can have a look soon and confirm whether the changes are ready.
PR merged, thank you!