GHSA-vfhx-5459-qhqh CI4MS Vulnerable to .env CRLF Injection via Unvalidated `host` Parameter in Install Controller
SummaryThe `Install::index()` controller reads the `host` POST parameter without any validation and passes it directly into `updateEnvSettings()`, which writes it into the `.env` file via `preg_replace()`. Because newline characters in the value are not stripped, an attacker can inject arbitrary configuration directives into the `.env` file. The install routes have CSRF protection explicitly disabled, and the `InstallFilter` can be bypassed when `cache('settings')` is empty (cache expiry or fresh deployment).DetailsIn `modules/Install/Controllers/Install.php`, the `$valData` array (lines 13-27) defines validation rules for all POST parameters **except** `host`. The `host` value is read at line 35:This value is passed to `updateEnvSettings()` (lines 89-101), which uses `preg_replace` with the raw value as the replacement string:Since the `env` template has all lines commented out (e.g., `# database.default.hostname = localhost`), the pattern does not match, and the value is appended verbatim — including any embedded newline characters. This allows injection of arbitrary key=value pairs into `.env`.The `dbpassword` field (line 17) is a secondary vector — its validation (`permit_empty|max_length[255]`) does not reject newline characters.**Access conditions:**CSRF is explicitly disabled for install routes (`InstallConfig.php:7-9`), confirmed consumed by `Filters.php:220-231,246-251`.`InstallFilter` (line 13) only blocks when **both** `.env` exists **and** `cache('settings')` is populated. The endpoint is accessible during fresh install or after cache expiry/clear.**Mitigation note:** `encryption.key` injection is NOT exploitable because `generateEncryptionKey()` (line 70) runs after `updateEnvSettings()` and overwrites all `encryption.key=` lines with a cryptographically random value. However, all other `.env` settings remain injectable.PoC**Scenario:** Application is deployed but cache has expired (or fresh install window).**Expected result:** The `.env` file will contain:These injected lines override the legitimate `app.baseURL` set earlier (CI4's DotEnv processes top-to-bottom; later values win for `putenv`), redirect the application base URL to an attacker-controlled domain, and modify session handling.**CSRF exploitation variant** (no direct access needed):ImpactAn unauthenticated attacker can inject arbitrary configuration into the `.env` file when the install endpoint is accessible (fresh deployment or cache expiry). This enables:**Application URL hijacking** — injecting `app.baseURL` to an attacker domain, causing password reset links, redirects, and asset loading to point to attacker infrastructure**Security downgrade** — disabling `forceGlobalSecureRequests`, CSP, or other security settings**Session manipulation** — changing session driver or save path configuration**Full application reconfiguration** — the `copyEnvFile()` method overwrites the existing `.env` with the template before applying updates, destroying the current configuration (denial of service)**Database redirect** — while not via the `host` injection itself (the host value is a legitimate DB config), injecting additional database config lines can alter connection behaviorThe attack is amplified by the absence of CSRF protection on the install endpoint, allowing exploitation via a malicious webpage visited by anyone on the same network.Recommended Fix**Add validation for the `host` parameter** — reject newlines and restrict to valid hostnames/IPs:**Sanitize all values in `updateEnvSettings()`** — strip newlines from replacement strings:**Add newline validation to `dbpassword`** — add `regex_match[/^[^\r\n]*$/]` to the validation rules.**Strengthen `InstallFilter`** — consider checking for a more reliable installation-complete indicator than cache state (e.g., a database table existence check or a dedicated lock file).
CVSS v3.1 score: 8.1