CVE-2026-54529 Overview
CVE-2026-54529 is an information exposure vulnerability in SQLAdmin, a flexible admin interface for SQLAlchemy models. The flaw resides in ModelView.sort_query within sqladmin/models.py. Versions prior to 0.27.1 accept the attacker-controlled sortBy list-view query parameter without enforcing the configured column_sortable_list server-side allow-list in self._sort_fields. The value is resolved with getattr and passed directly to relationship joins and order_by, allowing sorts on columns hidden from column_list and on related-model columns via dotted paths. This vulnerability is categorized under [CWE-20] Improper Input Validation and is fixed in version 0.27.1.
Critical Impact
The resulting row order forms an information-exposure oracle. Attackers can infer values of unexposed columns by observing ascending versus descending row order.
Affected Products
- SQLAdmin versions prior to 0.27.1
- Applications exposing SQLAdmin list views to untrusted or low-privilege users
- Deployments relying on column_list restrictions to hide sensitive columns
Discovery Timeline
- 2026-09-14 - CVE-2026-54529 published to NVD
- 2026-09-14 - Last updated in NVD database
Technical Details for CVE-2026-54529
Vulnerability Analysis
SQLAdmin's ModelView.sort_query handler reads the sortBy HTTP query parameter and forwards it into SQLAlchemy order_by clauses without validating the field name against the configured _sort_fields allow-list. Because the value is resolved with getattr against the model, any attribute is reachable, including columns intentionally omitted from column_list and columns of related models via dotted-path traversal that triggers implicit joins.
Sorting by a hidden column produces a deterministic ordering of visible rows. An attacker can reverse the sort direction to confirm relative ordering and pair sortBy with searchable or filterable columns plus pagination to progressively narrow the oracle toward specific values. Exact value recovery depends on the fields and data available in the target application.
Root Cause
The root cause is missing server-side validation of a user-supplied parameter against the maintainer-defined allow-list. column_sortable_list is enforced only at the UI layer, and the request handler trusts the incoming sortBy value. This is a classic [CWE-20] Improper Input Validation defect where allow-list logic exists but is not applied at the trust boundary.
Attack Vector
Exploitation requires only network access to a SQLAdmin list view. No authentication is required if the admin view is exposed to unauthenticated users, and no user interaction is required. An attacker crafts HTTP GET requests that pass arbitrary column names, including dotted relationship paths, as the sortBy parameter and observes the returned row ordering to build the oracle.
sort = request.query_params.get("sort", "asc")
if sort_by:
+ if sort_by not in self._sort_fields:
+ raise HTTPException(status_code=400, detail="Invalid sortBy parameter")
sort_fields = [(sort_by, sort == "desc")]
else:
sort_fields = self._get_default_sort()
Source: GitHub Commit 741635f. The patch rejects any sortBy value that is not in self._sort_fields by raising an HTTP 400 response before the value reaches order_by.
Detection Methods for CVE-2026-54529
Indicators of Compromise
- Repeated HTTP GET requests to SQLAdmin list-view endpoints with varying sortBy values that do not match any UI-exposed sortable column.
- Requests containing dotted-path sortBy values (for example, sortBy=relation.hidden_column) indicating relationship traversal attempts.
- Alternating sort=asc and sort=desc requests targeting the same sortBy parameter, consistent with oracle confirmation behavior.
Detection Strategies
- Instrument SQLAdmin views to log every sortBy value and compare it against the view's declared column_sortable_list.
- Deploy WAF or reverse-proxy rules that alert when sortBy query parameters contain values not present in an application-specific allow-list.
- Baseline normal admin usage patterns and flag high-volume paginated requests that cycle through many distinct sortBy values from a single source.
Monitoring Recommendations
- Forward admin-endpoint access logs to a centralized SIEM and retain query-parameter values for at least 90 days.
- Alert on bursts of 4xx responses from SQLAdmin list views once the patch is deployed, as these indicate blocked exploitation attempts.
- Monitor for anomalous authenticated sessions issuing high request rates against list endpoints with pagination and filter combinations.
How to Mitigate CVE-2026-54529
Immediate Actions Required
- Upgrade SQLAdmin to version 0.27.1 or later in all environments that expose the admin interface.
- Inventory all deployments using SQLAdmin and confirm the running version through dependency manifests such as requirements.txt, pyproject.toml, or poetry.lock.
- Restrict network access to admin views behind VPN, IP allow-lists, or authenticated reverse proxies until patching is complete.
Patch Information
The fix is available in SQLAdmin 0.27.1. The patched ModelView.sort_query validates the sortBy parameter against self._sort_fields and raises HTTPException(status_code=400) on mismatch. See the GitHub Security Advisory GHSA-ccg5-9c8w-xh6v and the SQLAdmin 0.27.1 release notes for full remediation details.
Workarounds
- Subclass ModelView and override sort_query to validate sortBy against self._sort_fields before invoking the parent implementation.
- Place a reverse-proxy or WAF rule in front of admin routes that rejects sortBy values not present in a per-view allow-list.
- Require authentication and role-based authorization on all SQLAdmin routes so that anonymous users cannot reach vulnerable list views.
# Upgrade SQLAdmin to the patched release
pip install --upgrade 'sqladmin>=0.27.1'
# Verify the installed version
python -c "import sqladmin; print(sqladmin.__version__)"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.