Summary
Horilla contains a code injection vulnerability in its list-view data export functionality, where authenticated input is incorporated into dynamically generated Python code.
An authenticated attacker who can submit crafted column data may cause arbitrary operating-system commands to run with the privileges of the Horilla application process.
Affected context
The vulnerability occurs in Horilla deployments using the list-view export feature before the relevant security fix. It requires the application to process user-controlled column parameters and construct a Python function definition from those values before evaluating the generated source.
Exploit preconditions
- Attack surface: Authenticated web access to the list-view export functionality
- Required access: A valid user account permitted to submit export-related column parameters
- Trigger point: Processing of the
columnsPOST parameter during export generation - Why exploitation is possible: User-controlled data is interpolated into Python source and passed to
exec(), allowing syntax that survives preliminary value parsing to influence function-definition evaluation
Why this happens
The underlying flaw is the construction and execution of Python source code using attacker-influenced values. Although the input is processed through a literal parser, that does not make subsequent source-code interpolation safe; the resulting function definition can evaluate expressions during creation.
This behavior maps to CWE-94: Improper Control of Generation of Code ('Code Injection'), because data from an authenticated request is treated as executable Python logic rather than as inert configuration or data.
Potential impact
- Arbitrary operating-system commands may execute under the application process account
- The Horilla application and its accessible data could be compromised
- Sensitive HR or CRM records may be read, altered, or deleted
- A privileged deployment may allow broader host or container compromise
- Attackers could establish persistence or use the application as a platform for lateral movement
General mitigation guidance
Mitigation generally focuses on removing dynamic source-code generation from request-driven workflows and reducing the trust placed in export parameters.
Common defensive patterns include:
- Replacing
exec()-based function construction with fixed, explicitly selected code paths - Treating column names and field selectors as data validated against an allowlist
- Separating parsing from execution and rejecting unexpected types, syntax, and values
- Running the application with a dedicated least-privilege account rather than elevated privileges
- Restricting container capabilities, filesystem access, and network permissions
- Limiting which authenticated roles can invoke export functionality and submit complex selectors
How teams detect issues like this
Organizations can look for:
- Static-analysis findings involving
exec(),eval(), dynamic function definitions, and string interpolation near execution APIs - Code-review signals where HTTP parameters are concatenated or formatted into Python source
- Tests that submit unexpected field names, delimiters, or expression-like values to export endpoints and verify that they remain data
- Web-application logs showing unusual export requests, repeated malformed column parameters, or command-related error patterns
- Policy enforcement that blocks dynamic code execution in request-processing paths and requires allowlisted field mappings

