The vulnerability (GHSA-jc7g-x28f-3v3h) in Listmonk allows low-privilege users to read sensitive system environment variables via template injection. This is due to the inclusion of dangerous functions (env and expandenv) from the Sprig template library, which are enabled by default.
The analysis of the provided patch (commit d27d2c32cf3af2d0b24e29ea5a686ba149b49b3e) reveals that two specific functions in Listmonk were responsible for making these Sprig functions available:
main.initTplFuncs (in cmd/init.go): This function initializes global template functions for the application.
manager.makeGnericFuncMap (in internal/manager/manager.go): This function prepares a map of template functions used within the manager's context.
Prior to the patch, both functions directly used sprig.GenericFuncMap() to populate the list of available template functions, thereby including env and expandenv. The fix applied in the patch modifies these two functions to explicitly delete env and expandenv from the map of Sprig functions before they are made available to the templating engine.
Therefore, these two functions, in their pre-patch state, are identified as the points in the Listmonk codebase that introduced the vulnerability by failing to restrict access to these powerful Sprig functions. An attacker with permissions to edit templates (e.g., in campaign content, as shown in the PoC) could then craft a template to call {{ env "VARIABLE_NAME" }} or {{ expandenv "$VARIABLE_NAME" }}, leading to the disclosure of potentially critical information like database credentials, API keys, or other secrets stored in environment variables. During exploitation, if a profiler were attached, calls originating from template processing would eventually trace back to the execution of these Sprig functions, which were made available by main.initTplFuncs or manager.makeGnericFuncMap (depending on the execution path). The functions themselves (initTplFuncs, makeGnericFuncMap) would appear in the call stack during the setup phase where template functions are registered, rather than during the direct exploitation of the env function call within a template. However, they are the direct enablers of the vulnerability.