Files
haproxy-manager-base/errors/403-waf.html
Josh Knapp c1331a592a
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 54s
waf-block page: escape literal % as %% (HAProxy lf-file expansion)
End-to-end test of the 403 page showed CSS `100%` rendering as `100`
and gradient stops `0%, 100%` rendering as `0, 100` — HAProxy's
`lf-file` directive runs log-format expansion over the file content,
and `%` is the format-escape character. Single `%` is consumed by
the expander.

Doubled every literal CSS percentage (`100%%`, `0%%`, etc.) so HAProxy
emits a single `%` in the rendered body. Format expressions like
`%[unique-id]` and `%[req.hdr(host)]` stay single-`%` — those are the
substitutions we want.

Added a comment block at the top of the file documenting the gotcha for
future editors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 05:48:14 -07:00

110 lines
3.5 KiB
HTML

<!DOCTYPE html>
<!--
Served by HAProxy via `lf-file` on Coraza WAF deny.
IMPORTANT: HAProxy's lf-file expansion treats `%` as the start of a
log-format expression. Literal percent signs (CSS 100%, gradient stops,
url-encoded data, etc.) MUST be doubled as `%%` or HAProxy will silently
swallow them. Expressions like `%[unique-id]` / `%[req.hdr(host)]` stay
single-`%` — those are the substitutions we want.
-->
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow">
<title>Request blocked &middot; %[req.hdr(host)]</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%%; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
color: #1f2937;
background: linear-gradient(135deg, #f9fafb 0%%, #eef2f7 100%%);
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
line-height: 1.5;
}
.card {
background: #fff;
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0,0,0,0.05), 0 12px 32px rgba(31,41,55,0.08);
max-width: 560px;
width: 100%%;
padding: 36px 40px;
}
.badge {
display: inline-block;
background: #fef3c7;
color: #92400e;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
padding: 4px 10px;
border-radius: 999px;
margin-bottom: 16px;
}
h1 { font-size: 22px; margin: 0 0 12px; color: #111827; }
p { margin: 0 0 14px; color: #374151; }
.ref {
background: #f3f4f6;
border: 1px solid #e5e7eb;
border-radius: 6px;
padding: 12px 14px;
margin: 20px 0;
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
font-size: 13px;
color: #111827;
word-break: break-all;
}
.ref-label {
display: block;
color: #6b7280;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.05em;
text-transform: uppercase;
margin-bottom: 4px;
font-family: inherit;
}
.owner {
border-top: 1px solid #e5e7eb;
margin-top: 24px;
padding-top: 20px;
color: #4b5563;
font-size: 14px;
}
.owner h2 { font-size: 14px; font-weight: 600; color: #111827; margin: 0 0 8px; }
a {
color: #1d4ed8;
text-decoration: none;
border-bottom: 1px solid transparent;
}
a:hover, a:focus { border-bottom-color: #1d4ed8; }
.small { font-size: 12px; color: #6b7280; margin-top: 16px; }
</style>
</head>
<body>
<main class="card" role="main">
<span class="badge">Access blocked</span>
<h1>Your request was blocked by our security filter</h1>
<p>The request to <strong>%[req.hdr(host)]</strong> looked suspicious to our web application firewall and was not delivered to the site.</p>
<p>This is automated. No one has reviewed the request yet.</p>
<div class="ref">
<span class="ref-label">Request reference</span>
%[unique-id]
</div>
<div class="owner">
<h2>Site owner?</h2>
<p>If you operate this site and believe this block is incorrect, please <a href="https://secure.anhonesthost.com/submitticket.php" rel="noopener">open a support ticket</a> and include the request reference above. Our team can look up exactly which rule fired and adjust it if it's a false positive.</p>
</div>
<p class="small">Reference IDs expire from our active logs after 14 days, so please open a ticket promptly if you'd like this investigated.</p>
</main>
</body>
</html>