mirror of
https://github.com/tmdinosaurcenter/kiosk-guestbook.git
synced 2026-06-04 00:17:44 -06:00
fix: enforce max input lengths on guestbook form
Adds FIELD_MAX constants and server-side length checks in the index route. Adds matching maxlength attributes on all form inputs so the browser enforces limits before submission.
This commit is contained in:
@@ -123,6 +123,14 @@ def load_banned_words():
|
|||||||
|
|
||||||
BANNED_WORDS = load_banned_words()
|
BANNED_WORDS = load_banned_words()
|
||||||
|
|
||||||
|
FIELD_MAX = {
|
||||||
|
'first_name': 100,
|
||||||
|
'last_name': 100,
|
||||||
|
'email': 254,
|
||||||
|
'location': 100,
|
||||||
|
'comment': 2000,
|
||||||
|
}
|
||||||
|
|
||||||
def contains_banned_words(text):
|
def contains_banned_words(text):
|
||||||
lower = text.lower()
|
lower = text.lower()
|
||||||
# Whole-word check (punctuation-stripped) — catches exact matches
|
# Whole-word check (punctuation-stripped) — catches exact matches
|
||||||
@@ -246,6 +254,14 @@ def index():
|
|||||||
if not (first_name and last_name and location):
|
if not (first_name and last_name and location):
|
||||||
error = "First name, last name, and location are required."
|
error = "First name, last name, and location are required."
|
||||||
logger.warning("Missing required fields.")
|
logger.warning("Missing required fields.")
|
||||||
|
elif (len(first_name) > FIELD_MAX['first_name'] or
|
||||||
|
len(last_name) > FIELD_MAX['last_name'] or
|
||||||
|
len(location) > FIELD_MAX['location']):
|
||||||
|
error = "A required field exceeds the maximum allowed length."
|
||||||
|
elif email and len(email) > FIELD_MAX['email']:
|
||||||
|
error = "Email address is too long."
|
||||||
|
elif comment and len(comment) > FIELD_MAX['comment']:
|
||||||
|
error = f"Comment is too long (max {FIELD_MAX['comment']:,} characters)."
|
||||||
elif email and not is_valid_email(email):
|
elif email and not is_valid_email(email):
|
||||||
error = "Invalid email address."
|
error = "Invalid email address."
|
||||||
logger.warning("Invalid email: %s", email)
|
logger.warning("Invalid email: %s", email)
|
||||||
|
|||||||
@@ -73,17 +73,17 @@
|
|||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="first_name" class="form-label">First Name(s):</label>
|
<label for="first_name" class="form-label">First Name(s):</label>
|
||||||
<input type="text" class="form-control" id="first_name" name="first_name" required />
|
<input type="text" class="form-control" id="first_name" name="first_name" maxlength="100" required />
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="last_name" class="form-label">Last Name:</label>
|
<label for="last_name" class="form-label">Last Name:</label>
|
||||||
<input type="text" class="form-control" id="last_name" name="last_name" required />
|
<input type="text" class="form-control" id="last_name" name="last_name" maxlength="100" required />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Email + Newsletter Block (fully fixed) -->
|
<!-- Email + Newsletter Block (fully fixed) -->
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="email" class="form-label">Email (Optional):</label>
|
<label for="email" class="form-label">Email (Optional):</label>
|
||||||
<input type="email" class="form-control" id="email" name="email" />
|
<input type="email" class="form-control" id="email" name="email" maxlength="254" />
|
||||||
|
|
||||||
<div class="form-check mt-2">
|
<div class="form-check mt-2">
|
||||||
<input class="form-check-input" type="checkbox" name="newsletter_opt_in" id="newsletter_opt_in"
|
<input class="form-check-input" type="checkbox" name="newsletter_opt_in" id="newsletter_opt_in"
|
||||||
@@ -96,13 +96,13 @@
|
|||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="location" class="form-label">Location:</label>
|
<label for="location" class="form-label">Location:</label>
|
||||||
<input type="text" class="form-control" id="location" name="location" required />
|
<input type="text" class="form-control" id="location" name="location" maxlength="100" required />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Comment field hidden by default -->
|
<!-- Comment field hidden by default -->
|
||||||
<div class="mb-3" id="comment-field" style="display: none;">
|
<div class="mb-3" id="comment-field" style="display: none;">
|
||||||
<label for="comment" class="form-label">Comment (Optional):</label>
|
<label for="comment" class="form-label">Comment (Optional):</label>
|
||||||
<textarea class="form-control" id="comment" name="comment" rows="3"></textarea>
|
<textarea class="form-control" id="comment" name="comment" rows="3" maxlength="2000"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary">Submit</button>
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user