Summary
Mautic's lead lookup action may allow SQL injection because a request-controlled field name is concatenated into a SQL column expression without strict validation. An attacker with a valid session may be able to manipulate the field parameter to alter database queries, depending on database permissions and deployment configuration.
Affected context
The issue occurs in Mautic's LeadBundle Ajax controller when the lead lookup action accepts a field parameter from an authenticated request. The value is passed through a general-purpose sanitizer that does not constrain it to valid column identifiers, and it is later incorporated into a repository query as a raw SQL expression. Deployments are most exposed when ordinary authenticated users can reach this action and the application database account has broad privileges.
Exploit preconditions
- Attack surface: The LeadBundle Ajax controller's lead lookup action
- Required access: A valid authenticated session; additional elevated permissions may not be required
- Trigger point: Processing of the request-controlled field parameter while constructing the lead query
- Why exploitation is possible: The parameter is concatenated into a SQL identifier expression rather than validated against an allowlist, and identifier values cannot be safely protected by ordinary bound-value parameters
Why this happens
The underlying bug is SQL injection caused by treating a request-controlled value as a trusted SQL identifier. General HTML-oriented sanitization does not establish that a value is a valid column name and does not remove all SQL syntax that may be meaningful in an expression. This maps to CWE-89: Improper Neutralization of Special Elements used in an SQL Command, because untrusted input reaches SQL construction without identifier validation or safe structural separation.
Potential impact
- An attacker may alter the intended database query
- Sensitive records may be disclosed
- Query results may be manipulated or filtered unexpectedly
- Application data may be modified or deleted if database privileges permit it
- Database availability could be affected through resource-intensive queries
- Broader compromise may be possible if excessive database permissions expose sensitive integration capabilities
General mitigation guidance
Mitigation generally focuses on separating SQL structure from request data and reducing the trust placed in dynamic field selectors.
Common defensive patterns include:
- Map accepted external field names to a fixed allowlist of known-safe column expressions
- Reject unknown, empty, or structurally invalid field values before query construction
- Use bound parameters for data values wherever parameters are supported
- Avoid constructing dynamic SQL identifiers directly from request input
- Enforce authorization checks consistently for controller actions that expose sensitive records
- Apply least privilege to the application database account
- Limit returned fields and records according to the requesting user's authorization scope
- Treat HTML escaping as presentation protection, not SQL or identifier validation
How teams detect issues like this
Detection approaches commonly include:
- Static analysis rules that flag string concatenation or interpolation of request parameters into SQL builders
- Code review checks for dynamic table names, column names, sort expressions, and filter fragments
- Tests that verify every externally supplied field selector is resolved through an explicit allowlist
- Runtime database monitoring for unexpected query structures, error patterns, and abnormal access to sensitive tables
- Policy enforcement requiring parameterized queries and centralized query-construction utilities
- Automated security review tools that identify request data flowing into raw SQL expressions

