Attached is a debdiff update for nagios4 in trixie addressing the CSRF vulnerability in cmd.cgi reported in #1136340. No CVE has been assigned upstream.
Package: nagios4
Version: 4.4.6-4.1+deb13u1
Target distribution: trixie-security
Closes: #1136340
Upstream fix:
https://github.com/NagiosEnterprises/nagioscore/commit/e5ed38e
Upstream disclosure:
https://www.nagios.com/security-disclosures/nagios-core/4-5-12/
This could break some installations, so I've also backported upstream PR #1055, which adds a `cgi_cookie_fail_open` cgi.cfg option (default 0 = secure) so there is a documented escape hatch, and added a section to README.Debian explaining this. Build-tested in pbuilder against trixie.The debian source package is available here: https://www.stuart.id.au/russell/private/nagios4_4.4.6-4.1.tar
Let me know what you would like me to do next. -- Regards Russell Stuart [email protected]
diff -Nru nagios4-4.4.6/debian/changelog nagios4-4.4.6/debian/changelog --- nagios4-4.4.6/debian/changelog 2024-06-03 08:57:17.000000000 +1000 +++ nagios4-4.4.6/debian/changelog 2026-05-22 20:45:00.000000000 +1000 @@ -1,3 +1,17 @@ +nagios4 (4.4.6-4.1+deb13u1) trixie-security; urgency=high + + * CSRF Security Fix backported from upstream 4.5.12 commit + e5ed38e53a5d65721520c7c67be0746d63da28cb (cgi/cmd.c and + html/index.php.in). See + https://www.nagios.com/security-disclosures/nagios-core/4-5-12/ + for the upstream disclosure. No CVE assigned. + Closes: #1136340. + * This can break third party integrations that POST to cmd.cgi + without first setting NagFormId (the CSRF check fails). Upstream + PR 1055 has been added as a workaround - see README.Debian. + + -- Russell Stuart <[email protected]> Fri, 22 May 2026 20:45:00 +1000 + nagios4 (4.4.6-4.1) unstable; urgency=medium * Non-maintainer upload. diff -Nru nagios4-4.4.6/debian/patches/95_CSRF-cookie-security-fix.patch nagios4-4.4.6/debian/patches/95_CSRF-cookie-security-fix.patch --- nagios4-4.4.6/debian/patches/95_CSRF-cookie-security-fix.patch 1970-01-01 10:00:00.000000000 +1000 +++ nagios4-4.4.6/debian/patches/95_CSRF-cookie-security-fix.patch 2026-05-22 20:12:49.000000000 +1000 @@ -0,0 +1,86 @@ +Author: Emmett Kapsner <[email protected]> +Origin: upstream, https://github.com/NagiosEnterprises/nagioscore/commit/e5ed38e53a5d65721520c7c67be0746d63da28cb +Description: CSRF security fix backported from upstream 4.5.12. + . + cgi/cmd.c: make the CSRF cookie mandatory (default formid_ok=ERROR, + not OK), generate a pseudo-random NagFormId cookie server-side in + cmd.cgi's document_header() and emit it via Set-Cookie with + SameSite=Strict. Previously the cookie was generated client-side + by JavaScript in html/index.php, which is bypassed by attacker pages. + html/index.php.in: remove the now-redundant client-side cookie setter. + . + See upstream's disclosure at + https://www.nagios.com/security-disclosures/nagios-core/4-5-12/ . + +--- a/cgi/cmd.c ++++ b/cgi/cmd.c +@@ -112,7 +112,7 @@ + + int main(void) { + int result = OK; +- int formid_ok = OK; ++ int formid_ok = ERROR; + + /* Initialize shared configuration variables */ + init_shared_cfg_vars(1); +@@ -219,7 +219,6 @@ + } + + if (cookie_form_id && *cookie_form_id) { +- formid_ok = ERROR; + if (form_id && *form_id) { + if (!strcmp(form_id, cookie_form_id)) + formid_ok = OK; +@@ -241,7 +240,7 @@ + /* the user wants to commit the command */ + else if(command_mode == CMDMODE_COMMIT) { + if (formid_ok == ERROR) /* we're expecting an id but it wasn't there... */ +- printf("<p>Error: Invalid form id!</p>\n"); ++ printf("<p>Error: Invalid or missing CSRF cookie!</p>\n"); + else + commit_command_data(command_type); + } +@@ -280,9 +279,29 @@ + strip_html_brackets(ecmd->default_comment); + } + ++/* generates and sets a pseudo-random cookie if one is not already set */ ++void set_cookie() { ++ if (!(cookie_form_id && *cookie_form_id)) { ++ unsigned long long n = ((unsigned long long)rand() << 32) | rand(); ++ char buffer[32]; ++ ++ snprintf(buffer, sizeof(buffer), "%llx", n); ++ ++ cookie_form_id = strdup(buffer); ++ if (!cookie_form_id) { ++ fprintf(stderr, "Memory allocation failed\n"); ++ exit(1); ++ } ++ ++ printf("Set-Cookie: NagFormId=%s; SameSite=Strict\r\n", cookie_form_id); ++ } ++} ++ + + void document_header(int use_stylesheet) { + ++ set_cookie(); ++ + if(content_type == WML_CONTENT) { + + printf("Content-type: text/vnd.wap.wml\r\n\r\n"); +--- a/html/index.php.in ++++ b/html/index.php.in +@@ -35,11 +35,6 @@ + <meta name="ROBOTS" content="NOINDEX, NOFOLLOW"> + <title>Nagios: <?php echo $_SERVER['SERVER_NAME']; ?></title> + <link rel="shortcut icon" href="images/favicon.ico" type="image/ico"> +- +- <script LANGUAGE="javascript"> +- var n = Math.round(Math.random() * 10000000000); +- document.cookie = "NagFormId=" + n.toString(16); +- </script> + </head> + + <frameset cols="180,*" style="border: 0px; framespacing: 0px"> diff -Nru nagios4-4.4.6/debian/patches/96_CSRF-cookie-fail-open-option.patch nagios4-4.4.6/debian/patches/96_CSRF-cookie-fail-open-option.patch --- nagios4-4.4.6/debian/patches/96_CSRF-cookie-fail-open-option.patch 1970-01-01 10:00:00.000000000 +1000 +++ nagios4-4.4.6/debian/patches/96_CSRF-cookie-fail-open-option.patch 2026-05-22 20:28:55.000000000 +1000 @@ -0,0 +1,97 @@ +Author: Emmett Kapsner <[email protected]> +Origin: upstream, https://github.com/NagiosEnterprises/nagioscore/pull/1055 +Description: Add `cgi_cookie_fail_open` config option for the CSRF cookie check. + . + The security fix in 95_CSRF-cookie-security-fix.patch unconditionally + rejects any request to cmd.cgi that arrives without a valid NagFormId + cookie. That is the secure default, but it also breaks legitimate + third-party integrations (custom dashboards, automation scripts, + add-ons like NagiosBP) that POST commands to cmd.cgi without first + visiting the web UI in the same browser session. + . + This patch (upstream PR 1055, merged 2026-04-03, scheduled for the + next upstream release after 4.5.12) adds a cgi.cfg option: + . + cgi_cookie_fail_open=0 (default: secure -- reject without cookie) + cgi_cookie_fail_open=1 (insecure: revert to pre-fix behaviour) + . + Setting it to 1 reopens the CSRF window, but is the only way to keep + those third-party integrations working without rewriting them to + authenticate via the UI first. + . + NOTE for Debian: this option is *not* in upstream 4.5.12, only in + the unreleased 4.5.13+. It is present in this 4.4.6-4.1+deb12u1 + stable security update so that bookworm users can opt back to the + old behaviour locally; it will disappear when the package is + upgraded to 4.5.12+ds via bookworm -> trixie. + +--- a/cgi/cgiutils.c ++++ b/cgi/cgiutils.c +@@ -72,6 +72,7 @@ + int ack_no_sticky = FALSE; + int ack_no_send = FALSE; + int tac_cgi_hard_only = FALSE; ++int cgi_cookie_fail_open = FALSE; + + time_t this_scheduled_log_rotation = 0L; + time_t last_scheduled_log_rotation = 0L; +@@ -448,6 +449,8 @@ + ack_no_send = (atoi(val) > 0) ? TRUE : FALSE; + else if(!strcmp(var, "tac_cgi_hard_only")) + tac_cgi_hard_only = (atoi(val) > 0) ? TRUE : FALSE; ++ else if (!strcmp(var, "cgi_cookie_fail_open")) ++ cgi_cookie_fail_open = (atoi(val) > 0) ? TRUE : FALSE; + else if (callback) + (*callback)(var,val); + } +--- a/cgi/cmd.c ++++ b/cgi/cmd.c +@@ -44,6 +44,7 @@ + + extern int ack_no_sticky; + extern int ack_no_send; ++extern int cgi_cookie_fail_open; + + #define MAX_AUTHOR_LENGTH 64 + #define MAX_COMMENT_LENGTH 1024 +@@ -112,7 +113,6 @@ + + int main(void) { + int result = OK; +- int formid_ok = ERROR; + + /* Initialize shared configuration variables */ + init_shared_cfg_vars(1); +@@ -218,6 +218,8 @@ + return OK; + } + ++ int formid_ok = cgi_cookie_fail_open ? OK : ERROR; ++ + if (cookie_form_id && *cookie_form_id) { + if (form_id && *form_id) { + if (!strcmp(form_id, cookie_form_id)) +--- a/sample-config/cgi.cfg.in ++++ b/sample-config/cgi.cfg.in +@@ -404,6 +404,21 @@ + + + ++# CGI CSRF COOKIE CHECK BEHAVIOR ++# This option controls how the CGI handles a missing CSRF Cookie. ++# 0 (default): Fail closed - reject the request if the CSRF cookie is ++# missing or invalid. This is more secure. ++# 1: Fail open - allow the request even if the CSRF cookie check fails. ++# This reduces CSRF protection but may be required for some third-party ++# integrations. ++# ++# WARNING: Enabling fail open weakens security and should only be used ++# if you fully understand the risk. ++ ++#cgi_cookie_fail_open=0 ++ ++ ++ + # COMMAND COMMENTS + # These options control whether or not comments are required, optional, + # or not allowed for specific commands. The format for each line is: diff -Nru nagios4-4.4.6/debian/patches/series nagios4-4.4.6/debian/patches/series --- nagios4-4.4.6/debian/patches/series 2020-08-19 21:36:35.000000000 +1000 +++ nagios4-4.4.6/debian/patches/series 2026-05-22 20:28:20.000000000 +1000 @@ -5,3 +5,5 @@ 80_no_phone_home.patch 90_turn-off-use-authentication.path 9103-fix-unknown-rpm-arch.patch +95_CSRF-cookie-security-fix.patch +96_CSRF-cookie-fail-open-option.patch diff -Nru nagios4-4.4.6/debian/README.Debian nagios4-4.4.6/debian/README.Debian --- nagios4-4.4.6/debian/README.Debian 2018-01-11 11:50:34.000000000 +1000 +++ nagios4-4.4.6/debian/README.Debian 2026-05-22 20:45:00.000000000 +1000 @@ -25,6 +25,44 @@ /etc/nagios4/cgi.cfg and /etc/nagios4/apache2.conf. +CSRF cookie in cmd.cgi +====================== + + The 4.4.6-4.1+deb13u1 security update (Debian bug #1136340) + backports the upstream CSRF fix from Nagios Core 4.5.12. cmd.cgi + now requires every command-submission request to carry a NagFormId + cookie that was previously issued by cmd.cgi itself; cookies + generated client-side in JavaScript (the pre-4.5.12 behaviour) are + no longer trusted. + + This change can break legitimate third-party integrations that + POST to /cgi-bin/nagios4/cmd.cgi without first visiting the Nagios + web UI in the same browser session. Typical examples are custom + dashboards, automation/orchestration scripts that submit external + commands via curl, mobile status panels, and add-ons such as + NagiosBP. + + The symptom is: instead of the command being passed to the Nagios + pipe at /var/lib/nagios4/rw/nagios.cmd, cmd.cgi returns an HTTP + 200 response whose body contains literally: + + Error: Invalid or missing CSRF cookie! + + Apache access logs show 200s (the error is HTML, not an HTTP + status), and /var/log/nagios4/nagios.log shows no incoming + command. + + If you cannot easily rewrite the integration to authenticate + through the UI first, you can opt back into the pre-fix behaviour + by setting the following in /etc/nagios4/cgi.cfg: + + cgi_cookie_fail_open=1 + + WARNING: this reopens the CSRF vulnerability that the fix was + intended to close. Use only as a transitional measure, and + restrict access to cmd.cgi at the apache2 layer in the meantime. + + Default Install ===============
OpenPGP_0xF5231C62E7843A8C.asc
Description: OpenPGP public key
OpenPGP_signature.asc
Description: OpenPGP digital signature

