Add CSRF, CAPTCHA, and input validation improvements
Introduces CSRF protection to all sensitive controller actions, integrates configurable CAPTCHA (reCAPTCHA v2/v3, Turnstile) for authentication and registration flows, and centralizes input validation via a new InputValidator helper. Adds new helpers and services for CSRF and CAPTCHA, updates settings and migration for CAPTCHA configuration, and enhances logging and error handling in TLD registry import processes. Also improves validation for user, domain, group, and profile inputs throughout the application.
This commit is contained in:
86
app/Views/auth/captcha-widget.php
Normal file
86
app/Views/auth/captcha-widget.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* CAPTCHA Widget Component
|
||||
* Renders the appropriate CAPTCHA widget based on settings
|
||||
*
|
||||
* Required variables:
|
||||
* - $captchaSettings: Array with 'provider' and 'site_key'
|
||||
*/
|
||||
|
||||
$provider = $captchaSettings['provider'] ?? 'disabled';
|
||||
$siteKey = $captchaSettings['site_key'] ?? '';
|
||||
|
||||
if ($provider === 'disabled' || empty($siteKey)) {
|
||||
return; // No CAPTCHA to render
|
||||
}
|
||||
?>
|
||||
|
||||
<!-- CAPTCHA Widget -->
|
||||
<div class="captcha-container mb-4">
|
||||
<?php if ($provider === 'recaptcha_v2'): ?>
|
||||
<!-- reCAPTCHA v2 -->
|
||||
<div class="g-recaptcha" data-sitekey="<?= htmlspecialchars($siteKey) ?>"></div>
|
||||
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
|
||||
|
||||
<?php elseif ($provider === 'recaptcha_v3'): ?>
|
||||
<!-- reCAPTCHA v3 (Invisible) -->
|
||||
<input type="hidden" id="captcha_response" name="captcha_response">
|
||||
<script src="https://www.google.com/recaptcha/api.js?render=<?= htmlspecialchars($siteKey) ?>"></script>
|
||||
|
||||
<?php elseif ($provider === 'turnstile'): ?>
|
||||
<!-- Cloudflare Turnstile -->
|
||||
<div class="cf-turnstile" data-sitekey="<?= htmlspecialchars($siteKey) ?>"></div>
|
||||
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
|
||||
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if ($provider === 'recaptcha_v3'): ?>
|
||||
<!-- reCAPTCHA v3 Form Submission Handler -->
|
||||
<script>
|
||||
// Store the original form submission handler
|
||||
const form = document.querySelector('form');
|
||||
const originalSubmit = form.onsubmit;
|
||||
|
||||
form.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
grecaptcha.ready(function() {
|
||||
grecaptcha.execute('<?= htmlspecialchars($siteKey) ?>', {action: 'submit'}).then(function(token) {
|
||||
document.getElementById('captcha_response').value = token;
|
||||
|
||||
// Call original submit handler if it exists
|
||||
if (originalSubmit && originalSubmit.call(form, e) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Submit the form
|
||||
form.submit();
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php elseif ($provider === 'recaptcha_v2' || $provider === 'turnstile'): ?>
|
||||
<!-- reCAPTCHA v2 / Turnstile Response Handler -->
|
||||
<script>
|
||||
// Add hidden input to capture response
|
||||
const form = document.querySelector('form');
|
||||
const captchaInput = document.createElement('input');
|
||||
captchaInput.type = 'hidden';
|
||||
captchaInput.name = 'captcha_response';
|
||||
captchaInput.id = 'captcha_response';
|
||||
form.appendChild(captchaInput);
|
||||
|
||||
// Capture response on form submit
|
||||
form.addEventListener('submit', function(e) {
|
||||
<?php if ($provider === 'recaptcha_v2'): ?>
|
||||
const response = grecaptcha.getResponse();
|
||||
<?php else: // turnstile ?>
|
||||
const response = turnstile.getResponse();
|
||||
<?php endif; ?>
|
||||
|
||||
captchaInput.value = response;
|
||||
});
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
@@ -35,6 +35,7 @@ ob_start();
|
||||
|
||||
<!-- Forgot Password Form -->
|
||||
<form method="POST" action="/forgot-password" class="space-y-5">
|
||||
<?= csrf_field() ?>
|
||||
<!-- Email Field -->
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium text-gray-700 mb-1.5">
|
||||
@@ -56,6 +57,9 @@ ob_start();
|
||||
<p class="text-xs text-gray-500 mt-1">Enter the email associated with your account</p>
|
||||
</div>
|
||||
|
||||
<!-- CAPTCHA Widget -->
|
||||
<?php include __DIR__ . '/captcha-widget.php'; ?>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<button
|
||||
type="submit"
|
||||
|
||||
@@ -25,6 +25,7 @@ ob_start();
|
||||
|
||||
<!-- Login Form -->
|
||||
<form method="POST" action="/login" class="space-y-5">
|
||||
<?= csrf_field() ?>
|
||||
<!-- Username Field -->
|
||||
<div>
|
||||
<label for="username" class="block text-sm font-medium text-gray-700 mb-1.5">
|
||||
@@ -85,6 +86,9 @@ ob_start();
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- CAPTCHA Widget -->
|
||||
<?php include __DIR__ . '/captcha-widget.php'; ?>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<button
|
||||
type="submit"
|
||||
|
||||
@@ -35,6 +35,7 @@ ob_start();
|
||||
|
||||
<!-- Registration Form -->
|
||||
<form method="POST" action="/register" class="space-y-4">
|
||||
<?= csrf_field() ?>
|
||||
<!-- Full Name Field -->
|
||||
<div>
|
||||
<label for="full_name" class="block text-sm font-medium text-gray-700 mb-1.5">
|
||||
@@ -163,6 +164,9 @@ ob_start();
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- CAPTCHA Widget -->
|
||||
<?php include __DIR__ . '/captcha-widget.php'; ?>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<button
|
||||
type="submit"
|
||||
|
||||
@@ -25,6 +25,7 @@ ob_start();
|
||||
|
||||
<!-- Reset Password Form -->
|
||||
<form method="POST" action="/reset-password" class="space-y-4">
|
||||
<?= csrf_field() ?>
|
||||
<!-- Hidden token field -->
|
||||
<input type="hidden" name="token" value="<?= htmlspecialchars($token ?? '') ?>">
|
||||
|
||||
@@ -95,6 +96,9 @@ ob_start();
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- CAPTCHA Widget -->
|
||||
<?php include __DIR__ . '/captcha-widget.php'; ?>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<button
|
||||
type="submit"
|
||||
|
||||
Reference in New Issue
Block a user