
Baserow 2.3.3 - SQL injection in formula index() JSONB array extraction
8.6
High
Detected by

Fluid Attacks AI SAST Scanner
Disclosed by
Miguel Gómez
Summary
Full name
Baserow 2.3.3 - SQL injection in formula index() JSONB array extraction
Code name
State
Public
Release date
Vulnerability name
SQL injection
Vulnerability type
Remotely exploitable
Yes
CVSS v4.0 vector string
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
CVSS v4.0 base score
8.6
Exploit available
Yes
CVE ID(s)
Description
Baserow 2.3.3 contains a SQL injection vulnerability in the index() formula function. A low-privileged authenticated user who can create or modify formula fields can provide an undocumented fourth argument that is treated as a SQL template and interpolated directly into a PostgreSQL expression.
The vulnerable expression is executed when Baserow recalculates formula field values. Because the generated SQL runs through Baserow's database connection, the injected SQL executes with the privileges of the Baserow PostgreSQL role rather than the permissions of the authenticated application user.
Successful exploitation allows an attacker to read and modify data outside their Baserow workspace permissions. The validated attack disclosed usernames and password hashes from auth_user and changed the attacker's auth_user.is_staff value to true, granting access to Baserow instance administration features.
Vulnerability
Root Cause
The public formula parser accepts an undocumented four-argument index() call:
The user-facing frontend help describes only two arguments. The third and fourth arguments are internal implementation details used to store the output mode and SQL extraction template.
The extra arguments are accepted as ordinary text:
This validation checks the Baserow formula type, not whether the fourth argument is a safe SQL template.
The fourth argument is copied into
value_sql:
For four-argument calls, the typed formula is accepted as-is:
During Django expression generation, the fourth argument is unwrapped:
The attacker-controlled SQL template is inserted into the query text:
JSONBArrayGetElement.as_sql() compiles the array and index expressions, builds an element expression, and then uses direct string formatting:
Django parameters protect only arr_params and idx_params. The value_sql string is already part of the SQL text and is not parameterized.
Formula recalculation executes the generated SQL:
Formula fields are recalculated after creation and update:
This makes exploitation immediate when the malicious Formula field is saved.
Impact
An authenticated low-privileged Baserow user with permission to create or modify fields in any editable table can execute SQL in the Baserow database context.
Confirmed impact:
Read usernames and password hashes from
auth_user.Modify
auth_user.is_stafffor the attacker's account.Gain Baserow instance administrator access after a fresh login or session refresh.
Current Commit Validation
Validated against the current local checkout:
Repository: https://github.com/baserow/baserow
Branch: develop
Local commit: bd22ab74880286aa8cadd002dadfabbcfc02d041
Local describe: 1.13.3-5286-gbd22ab748
Local version string: 2.3.3
Status: Confirmed present in the current local checkout and in tag 2.3.3.
Static validation:
BaserowIndex is registered as the user-facing index formula function and accepts between two and four arguments
(backend/src/baserow/contrib/database/formula/ast/function_defs.py:3055-3058).The frontend formula help documents only the safe two-argument usage, index(a file field, a number) and index(an array field, a number)
(web-frontend/modules/database/formula/functions.js:2562-2585).The backend type checker accepts the third and fourth arguments as formula text values
(backend/src/baserow/contrib/database/formula/ast/function_defs.py:3059-3068).If four arguments are supplied, BaserowIndex trusts the fourth argument as
value_sqland passes it toJSONBArrayGetElement (backend/src/baserow/contrib/database/formula/ast/function_defs.py:3091-3127).JSONBArrayGetElement.as_sql()insertsvalue_sqldirectly into SQL using Python string formatting:sql = f"({self.value_sql.format(elem=elem_sql)})" (backend/src/baserow/contrib/database/formula/expression_generator/django_expressions.py:198-204).Formula fields are recalculated through QuerySet.update(...) immediately after create or update, causing the generated expression SQL to be executed by PostgreSQL
(backend/src/baserow/contrib/database/fields/field_types.py:6075-6085andbackend/src/baserow/contrib/database/fields/field_types.py:6096-6112).The vulnerable implementation was introduced by PR #5066, merge commit
c3958f264b028557e65f003c7ebc6b7fd39b14de, and is contained in tags 2.2.0 through 2.3.3.
PoC
Preconditions
Baserow 2.3.3.
Application reachable at http://localhost:18081.
At least two accounts:
[email protected]: first registered account, instance administrator.
[email protected]: non-staff account.
The attacker is logged in as [email protected].
The attacker can create or edit fields in a database table.
Step by step
Create a workspace and a Database application as [email protected].
Create a table.
Rename the primary field to Files.
Change the primary field type to File.
Ensure the table has at least one row.
Create a Formula field named Privilege Escalation with:
Create another Formula field named User Hash Leak with:
Evidence of Exploitation
Video of exploitation:
Static evidence:

Our security policy
We have reserved the ID CVE-2026-19754 to refer to this issue from now on.
System Information
Baserow
Version: 2.3.3
Operating System: Any
References
GitHub Repository: https://github.com/baserow/baserow
Mitigation
There is currently no patch available for this vulnerability.
Credits
The vulnerability was discovered by Miguel Gomez from Fluid Attacks' Offensive Team using the AI SAST Scanner.
Timeline
Vulnerability discovered
Vendor contacted
Vendor replied
Public disclosure
Does your application use this vulnerable software?
During our free trial, our tools assess your application, identify vulnerabilities, and provide recommendations for their remediation.














