Collax Security Gateway: anonymous reflected cross-site scripting on the login page of both origins

An unauthenticated attacker who lures a victim to a crafted login link runs script on the login page and can rewrite the form to harvest administrator credentials.

Advisory ID: TP-2026-069
Product: Collax Security Gateway (German UTM, firewall, mail and SSL-VPN appliance; also affects Collax Business Server and Groupware Suite)
Vulnerability type: Reflected cross-site scripting (CWE-79)
CVE: pending (MITRE CNA-LR)
CVSS 3.1: 9.3 (Critical) · CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N
Vendor advisory: Collax release notes CSG 7.2.48
Affected versions: 7.2.46 and earlier
Fixed in: 7.2.48
Reported: 01 September 2026

Summary

The appliance login form is served anonymously at /.login by cgi-bin/nph-login-admin.cgi, which renders htmltemplates/login.tpl through HTML::Template. HTML::Template does not auto-escape, and login.tpl sets no ESCAPE=HTML on any variable. The ui and from parameters (the latter also derived from Referer and REQUEST_URI) are placed raw into double-quoted HTML attribute values in hidden form fields. Because CGI::param() URL-decodes the value, an encoded quote reaches the attribute as a literal quote and closes it. The /.login alias is wired on the admin interface (tcp/8001) and the WebAccess portal (tcp/80 and 443), served unauthenticated, and the appliance sends no CSP.

Root cause

login.tpl:91 emits value="<TMPL_VAR NAME=TARGET_UI>" and login.tpl:93 value="<TMPL_VAR NAME=HTTPD_LOCATION>", both inside a double-quoted attribute with no escaping.
nph-login-admin.cgi:281 builds the template with HTML::Template(die_on_bad_params => 0), whose default is no output escaping, and login.tpl carries zero ESCAPE= attributes.
nph-login-admin.cgi:132 assigns $ui = $q->param('ui') into TARGET_UI, and nph-login-admin.cgi:325-341 derives the URL for HTTPD_LOCATION from from, HTTP_REFERER or REQUEST_URI.
CGI::param() URL-decodes the value, so an encoded quote reaches the attribute as a literal quote and closes it.
The /.login alias is declared for both servers (etc/adminhttpd/.../akconfig_gui:61, etc/apache/.../akconfig_webaccess:118) with no header hardening anywhere in the Apache configuration.

Proof of Concept

Schematically: a login link carrying the payload in ui and from on the admin origin.

GET /.login?ui=<attribute breakout with script markup>&from=<attribute breakout> HTTP/1.1
Host: <gw>:8001

Both parameters break out of the value="..." attribute. The response carries no CSP, X-Content-Type-Options or X-Frame-Options. Verified at code level on 2026-09-01 under chroot+akrun; the browser firing follows from the injected context and the appliance-wide absence of CSP.

Impact

  • Anonymous script execution in the admin or WebAccess login origin, with no account.
  • Credential capture: injected JavaScript reads the username and password as the victim submits the login form and exfiltrates the plaintext admin credentials.
  • On an authenticated revisit, the script reads the non-HttpOnly auth_cookie, which is base64(user:password), disclosing the plaintext admin password.
  • Full control of the UTM, firewall and mail gateway follows from administrator credential disclosure.

References

Is Something Like This in Your Software?

Our team found this vulnerability during its work. Have your applications tested by the same specialists, with a penetration test from turingpoint.