diff --git a/src/protect/block-page.js b/src/protect/block-page.js new file mode 100644 index 0000000..e738b9a --- /dev/null +++ b/src/protect/block-page.js @@ -0,0 +1,89 @@ +// Full-page "Access Denied" block view, ported from the Patchstack WordPress plugin's +// sample.php. Served (instead of JSON) when a BLOCKED request is a top-level document navigation +// rather than an XHR/fetch — so a user who browses into a blocked URL sees a branded page, while +// programmatic clients still get JSON. Self-contained (inline CSS + base64 SVGs); exposes no WAF +// narrative and no rule details. + +function escapeHtml(s) { + return String(s).replace(/[&<>"']/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c])); +} + +/** @param {{ url?: string, code?: string }} opts @returns {string} a complete HTML document */ +export function renderBlockPage({ url = '', code = 'patchstack' } = {}) { + const safeUrl = escapeHtml(url); + const safeCode = escapeHtml(code || 'patchstack'); + return ` + +
+ + + + +