[BUG] sidekiq_alive binds to 0.0.0.0:7433 by default on Linux/VM installs, causing 100% CPU lockup from external TCP scans
Describe the bug
In PR #12008 (commit 2a5ecf84a1), the sidekiq_alive gem was added to the Gemfile to provide a healthcheck probe on port 7433.
However, no initializer (config/initializers/sidekiq_alive.rb) or environment variable configuration was provided. On standard self-hosted Linux (systemd / VM / bare-metal) deployments, sidekiq_alive defaults to binding to 0.0.0.0:7433, exposing the internal health check port directly to the public internet.
Furthermore, sidekiq_alive-2.5.0's built-in http_server.rb contains an infinite loop bug on client disconnect / EOF. In SidekiqAlive::HttpServer#serve:
# parse HTTP headers
while (line = io.gets) !~ /^(\n|\r)/
if line =~ /^([\w-]+):\s*(.*)$/
request.header[::Regexp.last_match(1)] = ::Regexp.last_match(2).strip
end
endWhen an external network crawler or port scanner (e.g. ZGrab, Shodan, automated scanner bots) connects to port 7433 and closes the TCP connection without sending valid HTTP headers, io.gets returns nil. Because nil !~ /^(\n|\r)/ evaluates to true, the loop becomes while true and never terminates, spinning at 100% CPU on the Sidekiq Ruby thread indefinitely.
In our production Linux VM, a single crawler connection trapped thread gserver.rb:264 in this loop, consuming 100% of an entire CPU core continuously for hours, starving Sidekiq job processing and degrading overall server performance.
To Reproduce
- Deploy Chatwoot on an Ubuntu Linux VM following the official self-hosted Linux installation guide without a host-level firewall.
- Verify that port 7433 is publicly listening on
0.0.0.0:ss -tlpn | grep 7433 # LISTEN 0 4096 0.0.0.0:7433 users:(("ruby",pid=...,fd=...)) - Send a TCP handshake / raw connection (or wait for an internet scanner probe):
nc -z <SERVER_PUBLIC_IP> 7433 - Inspect threads under Sidekiq:
top -H -p <SIDEKIQ_PID> - A Ruby thread named
gserver.rb:264gets permanently trapped in the loop and consumes 100% CPU.
Expected behavior
sidekiq_aliveshould bind to127.0.0.1by default on non-containerized environments (or be configurable viaSIDEKIQ_ALIVE_HOST)..env.exampleshould documentSIDEKIQ_ALIVE_HOST=127.0.0.1andSIDEKIQ_ALIVE_PORT=7433.- Chatwoot should provide a
config/initializers/sidekiq_alive.rbto ensure safe localhost defaults.
Environment
Linux VM
Cloud Provider
Other [please specify in the description]
Operating system
Ubuntu 22.04 LTS
Proposed Fix
Code Level: Add
config/initializers/sidekiq_alive.rb:if defined?(SidekiqAlive) SidekiqAlive.setup do |config| config.host = ENV.fetch('SIDEKIQ_ALIVE_HOST', '127.0.0.1') config.port = Integer(ENV.fetch('SIDEKIQ_ALIVE_PORT', 7433)) end endConfiguration Level: Add to
.env.example:# Sidekiq Health Check (SidekiqAlive) # Defaults to 127.0.0.1 to avoid exposing the probe port publicly on VM installations SIDEKIQ_ALIVE_HOST=127.0.0.1 SIDEKIQ_ALIVE_PORT=7433Deployment / Docs Level: Update
chatwoot-worker.1.servicetemplate and self-hosted documentation to includeSIDEKIQ_ALIVE_HOST=127.0.0.1.
Source: chatwoot/chatwoot