CVE-2026-61551 Overview
CVE-2026-61551 is an unbounded recursion vulnerability in Icinga 2, an open source monitoring system. The flaw resides in the JSON parsing paths of the Icinga 2 service exposed on TCP port 5665. Deeply nested JSON input exhausts the call stack because parsing depth is not bounded, causing the process to crash. Unauthenticated remote attackers can reach these code paths over the network and trigger a denial of service against the monitoring daemon. The issue is tracked as [CWE-674: Uncontrolled Recursion] and is fixed in versions 2.14.9, 2.15.4, and 2.16.2. Possible code execution has not been demonstrated by the maintainers.
Critical Impact
An unauthenticated remote attacker can crash the Icinga 2 monitoring daemon by sending crafted deeply nested JSON to TCP port 5665, disabling infrastructure monitoring visibility.
Affected Products
- Icinga 2 versions prior to 2.14.9
- Icinga 2 versions prior to 2.15.4 (2.15.x branch)
- Icinga 2 versions prior to 2.16.2 (2.16.x branch)
Discovery Timeline
- 2026-09-18 - CVE-2026-61551 published to NVD
- 2026-09-24 - Last updated in NVD database
Technical Details for CVE-2026-61551
Vulnerability Analysis
Icinga 2 uses the nlohmann::json SAX interface through a custom JsonSax handler to parse incoming JSON messages. Before the fix, the parser did not track or limit nesting depth. Each nested object or array pushes a new frame onto the parser's call stack. Sufficiently deep nesting exhausts the thread's stack, terminating the Icinga 2 process with a segmentation fault. The impacted JsonDecode function is reachable from the cluster protocol handler bound to TCP port 5665, which accepts connections from remote peers before authentication is completed.
Root Cause
The root cause is uncontrolled recursion in the JSON deserialization routine in lib/base/json.cpp. The JsonSax visitor did not enforce a maximum depth on start_object and start_array callbacks. Attacker-controlled input therefore dictates the recursion depth, allowing stack exhaustion.
Attack Vector
An unauthenticated remote attacker who can reach TCP port 5665 sends a crafted payload consisting of many nested JSON containers (for example, [[[[[...]]]]]). The Icinga 2 daemon parses the payload, exhausts the call stack, and terminates. Repeated requests prevent the service from recovering, resulting in a sustained denial of monitoring capability.
// Patch: lib/base/json.cpp - JsonDecode: add depth limit
class JsonSax : public nlohmann::json_sax<nlohmann::json>
{
public:
explicit JsonSax(std::size_t depthLimit) : m_DepthLimit(depthLimit) {}
bool null() override;
bool boolean(bool val) override;
bool number_integer(number_integer_t val) override;
// Patch: lib/base/configobject.cpp - explicit unbounded depth for trusted paths
void ConfigObject::RestoreObject(const String& message, int attributeTypes)
{
Dictionary::Ptr persistentObject = JsonDecode(message, std::numeric_limits<size_t>::max());
String type = persistentObject->Get("type");
String name = persistentObject->Get("name");
}
// Source: https://github.com/Icinga/icinga2/commit/391504eaa9ed9aee81f84008c57ec821974b74ee
The patch introduces a depthLimit parameter in the JsonSax constructor and enforces it inside container-open callbacks. Trusted local persistence paths such as ConfigObject::RestoreObject explicitly opt into an unbounded limit, while all network-reachable callers use a bounded default.
Detection Methods for CVE-2026-61551
Indicators of Compromise
- Unexpected termination or repeated restarts of the icinga2 process, often accompanied by segmentation fault entries in system logs (journalctl -u icinga2, /var/log/icinga2/).
- Inbound TCP connections to port 5665 from unexpected sources immediately preceding a crash.
- Network captures showing JSON payloads with abnormally deep bracket nesting sent to the cluster port.
Detection Strategies
- Monitor process supervision events for icinga2 exits with non-zero status and correlate with connection logs on TCP 5665.
- Deploy network inspection rules that flag JSON payloads exceeding a reasonable nesting threshold (for example, more than 100 levels) directed at Icinga 2 nodes.
- Track the running Icinga 2 version across the fleet and alert on any host still exposing a version older than 2.14.9, 2.15.4, or 2.16.2.
Monitoring Recommendations
- Aggregate host, process, and network telemetry in a centralized data lake to correlate service crashes with upstream network activity on port 5665.
- Alert on availability gaps in Icinga 2 check results, since a crash silently suppresses downstream monitoring alerts.
- Baseline the volume and size of cluster protocol traffic and alert on sudden anomalies from untrusted peers.
How to Mitigate CVE-2026-61551
Immediate Actions Required
- Upgrade Icinga 2 to 2.14.9, 2.15.4, or 2.16.2 depending on the deployed branch.
- Restrict inbound access to TCP port 5665 to known cluster peers using host or network firewalls until patching completes.
- Enable automatic restart of the icinga2 service via systemd to reduce dwell time of any successful crash.
Patch Information
The fix is delivered in Icinga 2 releases v2.14.9, v2.15.4, and v2.16.2. Relevant commits include 391504e, 3d91666, 4964d24, and ed163a8, consolidated through Pull Request #10908. See the Icinga Security Advisory GHSA-wh38-wg57-5w7g and the Icinga blog release note for v2.16.2.
Workarounds
- Block or ACL-restrict inbound connections to TCP port 5665 so only trusted Icinga cluster members can reach the API and cluster protocol.
- Place Icinga 2 endpoints behind a dedicated management VLAN or VPN and deny public reachability.
- Configure systemd to auto-restart icinga2 on failure to preserve monitoring availability while patching is scheduled.
# Restrict TCP 5665 to known cluster peers using nftables
nft add rule inet filter input tcp dport 5665 ip saddr != { 10.0.0.10, 10.0.0.11 } drop
# Ensure the Icinga 2 service auto-restarts after a crash
sudo systemctl edit icinga2
# Add the following override:
# [Service]
# Restart=always
# RestartSec=5s
sudo systemctl daemon-reload
sudo systemctl restart icinga2
# Verify the installed version meets the fixed release
icinga2 --version
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

