Try out a dumb captcha field

This commit is contained in:
Yannik Rödel 2022-07-24 18:15:58 +02:00
parent 3bcd963851
commit 45ab77d754

View file

@ -8,7 +8,7 @@ import hmac
import mimetypes import mimetypes
import os import os
import secrets import secrets
from typing import Any, Optional, overload, IO from typing import Any, Optional, overload
import itsdangerous import itsdangerous
import requests import requests
@ -24,12 +24,14 @@ def fail(status: str, reason: str) -> None:
HONEYPOT_FIELD_NAME = "addressline1" HONEYPOT_FIELD_NAME = "addressline1"
CAPTCHA_FIELD_NAME = "question"
CAPTCHA_FIELD_QUESTION = "Welcher Fluss fließt durch Würzburg?"
CAPTCHA_FIELD_VALUE = "Main"
SITE_DIRECTORY = os.environ.get("SITE_DIRECTORY", "") SITE_DIRECTORY = os.environ.get("SITE_DIRECTORY", "")
request_uri = os.environ.get("REQUEST_URI", "").lower().rstrip("/") request_uri = os.environ.get("REQUEST_URI", "").lower().rstrip("/")
serializer = itsdangerous.URLSafeSerializer("secret key", "salt") serializer = itsdangerous.URLSafeSerializer("secret key", "salt")
cookies = dict[str, str]() cookies = dict[str, str]()
for entry in os.environ.get("HTTP_COOKIE", "").split(";"): for entry in os.environ.get("HTTP_COOKIE", "").split(";"):
name, *value = entry.lstrip(" ").split("=", 1) name, *value = entry.lstrip(" ").split("=", 1)
@ -71,15 +73,24 @@ match os.environ.get("REQUEST_METHOD", "").upper():
# a) only one form on the site and # a) only one form on the site and
# b) the <form> tag doesn't end on the same line. # b) the <form> tag doesn't end on the same line.
if "</form" in line.lower(): if "</form" in line.lower():
print(f'<input type="hidden" name="csrftoken" value="{csrf_token}" />') print(
f'<input type="hidden" name="csrftoken" value="{csrf_token}" />')
print(f'<label class="form-input">')
print(f'<span>{CAPTCHA_FIELD_QUESTION}</span>')
print(
f'<input type="text" name="{CAPTCHA_FIELD_NAME}" value="" placeholder="Gebe hier \'{CAPTCHA_FIELD_VALUE}\' ein." autocomplete="off" />')
print(f'</label>')
print(f'<label class="form-input">') print(f'<label class="form-input">')
print(f'<span>Bitte lasse dieses Feld leer:</span>') print(f'<span>Bitte lasse dieses Feld leer:</span>')
print(f'<input type="text" name="{HONEYPOT_FIELD_NAME}" value="" placeholder="Hier nichts eingeben." tabindex="-1" autocomplete="off" />') print(
f'<input type="text" name="{HONEYPOT_FIELD_NAME}" value="" placeholder="Hier nichts eingeben." tabindex="-1" autocomplete="off" />')
print(f'</label>') print(f'</label>')
print(f'<script type="text/javascript">') print(f'<script type="text/javascript">')
print(f'document.querySelector("input[name={HONEYPOT_FIELD_NAME}]").parentNode.classList.add("isolated")') print(
f'document.querySelector("input[name={HONEYPOT_FIELD_NAME}]").parentNode.classList.add("isolated")')
print(f'</script>') print(f'</script>')
print(line) print(line)
@ -138,9 +149,12 @@ if not hmac.compare_digest(csrf_token, given_csrf_token):
# If the honeypot field was not empty, back off. # If the honeypot field was not empty, back off.
if get_form_value(HONEYPOT_FIELD_NAME, ""): if (
fail("200 OK", f"Invalid value for field: {HONEYPOT_FIELD_NAME}") get_form_value(HONEYPOT_FIELD_NAME, "")
or get_form_value(CAPTCHA_FIELD_NAME,
"").lower().strip() != CAPTCHA_FIELD_VALUE
):
fail("200 OK", f"Invalid value for field: {CAPTCHA_FIELD_NAME}")
# Extract all the actually provided form data. This is different from form to # Extract all the actually provided form data. This is different from form to
# form (see the match block below). # form (see the match block below).