Security hardening and accessibility improvements (v1.1.0)

Address findings from security audit: wrap inline JSON.parse in
try/catch to prevent consent flow failure on corrupted cookies,
allowlist admin tab parameter, clamp consent_expiry server-side,
escape all server values in admin JS table builder, fix focus trap
listener cleanup, add aria-labelledby and banner focus for screen
readers, skip frontend loading during AJAX.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-18 10:32:16 +00:00
parent 0a73181ea7
commit 2294c8eda7
7 changed files with 146 additions and 24 deletions

View File

@@ -72,6 +72,9 @@
hideBanner();
showWidget();
} else {
// Move focus to banner so screen readers announce it.
banner.focus();
// --- Banner buttons (only needed for first-time visitors) ---
var acceptBtn = banner.querySelector('[data-att-cc="accept-all"]');
@@ -103,6 +106,9 @@
// --- Helper functions ---
// Tracks the current focus trap handler for cleanup.
var activeTrapHandler = null;
function hideBanner() {
banner.setAttribute('aria-hidden', 'true');
banner.classList.add('att-cc-hidden');
@@ -134,6 +140,12 @@
modal.classList.remove('att-cc-modal--open');
document.body.classList.remove('att-cc-modal-active');
// Clean up focus trap listener.
if (activeTrapHandler) {
modal.removeEventListener('keydown', activeTrapHandler);
activeTrapHandler = null;
}
// Return focus to the widget if visible, otherwise the banner prefs button.
if (widget && widget.style.display !== 'none') {
widget.focus();
@@ -174,7 +186,6 @@
function handleKeydown(e) {
if (e.key === 'Escape') {
closeModal();
element.removeEventListener('keydown', handleKeydown);
return;
}
@@ -195,6 +206,7 @@
}
}
activeTrapHandler = handleKeydown;
element.addEventListener('keydown', handleKeydown);
}
})();