Collax Security Gateway: OS command injection in the Squid rule tester lets a delegated proxyadmin run commands as root
A delegated proxy administrator scoped to web-proxy rule filtering obtains arbitrary command execution as admin and then root through the unvalidated url and username fields.
Advisory ID: TP-2026-072
Product: Collax Security Gateway (German UTM, firewall, mail and SSL-VPN appliance; also affects Collax Business Server and Groupware Suite)
Vulnerability type: OS command injection (CWE-78)
CVE: pending (MITRE CNA-LR)
CVSS 3.1: 9.9 (Critical) · CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
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 admin interface supports delegated administration: a user granted only the proxyadmin role may open the 'Rule Analysis' form (forms/squid_rule_tester.form:4). The JSON-RPC dispatcher authorises any holder of role.proxyadmin for this form, not only a full administrator. The url and username fields are declared typehint='plain' (clif/clif.squid_rule_tester.pl:92,94) and receive no format validation. RuleTester.pm interpolates them into a double-quoted shell command, sprintf('suwrap root squidguardRuleTest "%s" "%s" "%s" "%s"', $url, ...) (AKLib/Squid/RuleTester.pm:84), and runs it through open my $ph, '-|', $cmd (RuleTester.pm:86), a scalar pipe that spawns /bin/sh. The values are also stored and re-shelled when the test history renders. Because suwrap is setuid root:admin mode 4750, admin escalates to root in one hop.
Root cause
RuleTester.pm builds a shell command with sprintf('suwrap root squidguardRuleTest "%s" "%s" "%s" "%s"', $url, $ip, $user, ...) (AKLib/Squid/RuleTester.pm:84) and runs it through open my $ph, '-|', $cmd (RuleTester.pm:86), which invokes /bin/sh.
The url and username fields are typehint='plain' and pass no metacharacter filter (clif/clif.squid_rule_tester.pl:92,94), so a ", $(...) or ` in url escapes the double quotes.
The value was meant to be a test URL the suwrap helper feeds to squidGuard (suwrap/squidguardRuleTest:10,15), not a shell fragment.
The JSON-RPC dispatcher grants the form to any holder of role.proxyadmin (forms/squid_rule_tester.form:4), a role below full administrator.
The injected shell runs as OS user admin (adminhttpd.conf:119-120), suwrap is setuid root:admin mode 4750, and the stored url and username are re-shelled when the history renders, so the injection persists.
Proof of Concept
Schematically: sign in to :8001 as a user holding only role.proxyadmin and open the 'Rule Analysis' form (/json/
{"method":"master","params":[{"url":"<command-substitution breakout>","userip":"1.2.3.4","username":"-"}]}
testRule interpolates the stored url into the shell command and executes it; the substitution fires at shell-parse time, before squidguardRuleTest. Verified on 2026-09-01 with a uid=0(root) marker under chroot+akrun.
Impact
- A delegated proxy administrator scoped to web-proxy filtering runs arbitrary OS commands as admin and then root.
- The stored url and username are re-executed on history render, so the injection is persistent.
- Full compromise of the gateway from a limited delegated credential, a privilege-boundary break.
- No CSP, X-Frame-Options or X-Content-Type-Options header anywhere on the appliance.
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.
