Skip to content

Fix broken 'html' HAProxy converter in ban-with-contact.html#167

Merged
sabban merged 1 commit into
feature/no-lua-haproxy-renderingfrom
fix/ban-contact-url-html-converter
Jul 3, 2026
Merged

Fix broken 'html' HAProxy converter in ban-with-contact.html#167
sabban merged 1 commit into
feature/no-lua-haproxy-renderingfrom
fix/ban-contact-url-html-converter

Conversation

@sabban

@sabban sabban commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • PR Fix XSS vulnerability: validate URL scheme and HTML-escape contact_us… #166 tried to HTML-escape contact_us_url in the native HAProxy template using a ,html converter, but HAProxy has no such converter. Verified against the actual haproxy:2.9.7-alpine image used by this repo's docker-compose: haproxy -c fails with unknown converter 'html', so any deployment enabling ban-with-contact.html (via the lf-file directive in haproxy.cfg) fails to start.
  • Moves escaping to the single point where contact_us_url is produced — internal/remediation/ban/root.go, via stdlib html.EscapeString — after the existing scheme allowlist check, instead of duplicating escaping logic in both the Lua template renderer and the HAProxy config.
  • Removes the now-redundant hand-rolled html_escape() in lua/crowdsec.lua; the Lua ban template consumes the already-escaped value.
  • Reverts templates/ban-with-contact.html to a plain %[var(txn.crowdsec.contact_us_url)] (no converter needed).

Test plan

  • go build ./... and go vet ./internal/remediation/ban/... pass
  • Re-validated templates/ban-with-contact.html against real haproxy:2.9.7-alpine via haproxy -c — now exits 0 (previously failed with unknown converter 'html')
  • Manual smoke test of the ban-with-contact page in a running stack

🤖 Generated with Claude Code

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 <noreply@anthropic.com>
@sabban
sabban merged commit ce74d27 into feature/no-lua-haproxy-rendering Jul 3, 2026
1 check passed
@sabban
sabban deleted the fix/ban-contact-url-html-converter branch July 3, 2026 09:42
sabban added a commit that referenced this pull request Jul 6, 2026
* golangci-lint

* Make HAProxy Lua rendering optional

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix: strip surrounding quotes from string literals in Lua template if-statement parser

* Fix ACL content-negotiation, charset, captcha status, Docker Lua volume, template a11y (#165)

Fix review findings: ACL content-negotiation, charset, captcha status, Docker Lua volume, template accessibility

- Replace '-m sub text' (overly broad, matched text/plain) with 'text/html' substring match
- Add 'html_rejected' ACL to exclude clients sending text/html;q=0 from HTML rendering
- Change captcha non-HTML response from 403 to 200 to preserve the Lua handler's semantics
- Add charset=utf-8 to all HTML Content-Type response headers
- Use regsub(&,\&amp;,g) to HTML-encode '&' in contact URL href in ban-with-contact.html
- Fix <div> dark-mode-toggle to <button> and collapse duplicate SVG class in ban.html and captcha.html
- Restore lua: volume in docker-compose.yaml as commented-out for optional Lua rendering mode
- Document template path customisation and lf-file startup validation gap in README

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Fix typo: rename agaisnt to against in template.lua

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Fix XSS vulnerability: validate URL scheme and HTML-escape contact_us… (#166)

Fix XSS vulnerability: validate URL scheme and HTML-escape contact_us_url

- Validate contact_us_url scheme (only http/https/mailto allowed) in Go
  before setting the HAProxy variable, preventing javascript: XSS
- Use HAProxy html converter in ban-with-contact.html for proper
  HTML-escaping (replaces incomplete regsub that only handled ampersands)
- Add html_escape() helper in crowdsec.lua and apply it to contact_us_url
  before passing it to the Lua template renderer

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>

* Fix broken 'html' HAProxy converter in ban-with-contact.html (#167)

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 <noreply@anthropic.com>

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant