From f80f829d65db5be0956685dbbfa6c38e353baa00 Mon Sep 17 00:00:00 2001 From: sabban Date: Fri, 3 Jul 2026 11:39:29 +0200 Subject: [PATCH] Fix broken 'html' HAProxy converter in ban-with-contact.html MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #166 escaped contact_us_url via a `,html` converter in the native HAProxy template, but HAProxy has no such converter — `haproxy -c` rejects the config with "unknown converter 'html'", breaking any deployment that enables the ban-with-contact page. Move the escaping to the single point where contact_us_url is produced (Go, via html.EscapeString) instead of duplicating it in both the Lua template renderer and the HAProxy config. Both the Lua and native HAProxy templates now consume the already-escaped value, so neither needs its own escaping logic. Co-Authored-By: Claude Sonnet 5 --- internal/remediation/ban/root.go | 3 ++- lua/crowdsec.lua | 6 +----- templates/ban-with-contact.html | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/internal/remediation/ban/root.go b/internal/remediation/ban/root.go index 323518a2..d7693535 100644 --- a/internal/remediation/ban/root.go +++ b/internal/remediation/ban/root.go @@ -1,6 +1,7 @@ package ban import ( + "html" "net/url" "github.com/dropmorepackets/haproxy-go/pkg/encoding" @@ -29,5 +30,5 @@ func (b *Ban) InjectKeyValues(writer *encoding.ActionWriter) { contactURL = "" } } - _ = writer.SetString(encoding.VarScopeTransaction, "contact_us_url", contactURL) + _ = writer.SetString(encoding.VarScopeTransaction, "contact_us_url", html.EscapeString(contactURL)) } diff --git a/lua/crowdsec.lua b/lua/crowdsec.lua index 0c1442b4..d457f8f8 100644 --- a/lua/crowdsec.lua +++ b/lua/crowdsec.lua @@ -53,10 +53,6 @@ end local runtime = {} -local function html_escape(s) - return s:gsub('&', '&'):gsub('<', '<'):gsub('>', '>'):gsub('"', '"') -end - -- Loads the configuration local function init() BAN_TEMPLATE_PATH = os.getenv("CROWDSEC_BAN_TEMPLATE_PATH") @@ -137,7 +133,7 @@ function runtime.Handle(txn) if remediation == "ban" then reply:set_body(runtime.ban.render({ - ["contact_us_url"]=html_escape(get_txn_var(txn, "crowdsec.contact_us_url")), + ["contact_us_url"]=get_txn_var(txn, "crowdsec.contact_us_url"), })) end diff --git a/templates/ban-with-contact.html b/templates/ban-with-contact.html index 9ddb7b4f..e794c632 100644 --- a/templates/ban-with-contact.html +++ b/templates/ban-with-contact.html @@ -17,7 +17,7 @@

CrowdSec Access Forbidden

You are unable to visit the website.

- + Contact Us