The vulnerability lies in the improper handling of user input within JSON and RichText field queries for databases using the Drizzle adapter in Payload CMS. An attacker could craft a malicious query that, when processed, would be executed by the database, leading to a blind SQL injection. This would allow the unauthorized extraction of sensitive data.
The investigation started by comparing the git tags for the last vulnerable version (v3.72.0) and the first patched version (v3.73.0). A specific commit, 4f5a9c28346aaea78d53240166000d7210c35fc7, was identified as the security patch. This commit, while titled as a bug fix for a different issue, contains the crucial security fix.
The key change is within the getBuildQueryJoinQuery function located in packages/db-drizzle/src/queries/getBuildQueryJoinQuery.ts. Before the patch, user-controlled values were being directly concatenated into the SQL query string. The patch modifies this function to use parameterized queries, where user input is treated as data and not as part of the SQL command. This is evident from the change from sql(${jsonQuery}) to `sql`(${sql.raw(jsonQuery)}), which, in context of the broader changes in the associated pull request, is part of a shift to safer, parameterized queries. This prevents the SQL injection vulnerability.