{"id":"CVE-2026-46645","aliases":["EUVD-2026-36168","GHSA-54mc-gghv-4cfj","PYSEC-2026-3073"],"status":"published","title":"SQLAdmin: Authorization Bypass on `ajax_lookup`","description":"SQLAdmin is a flexible Admin interface for SQLAlchemy models. Prior to version 0.25.1, the ajax_lookup endpoint in application.py bypasses the is_accessible() access control check that all other endpoints enforce. If a developer restricts model access by overriding is_accessible(), an authenticated user can still query that model's data through the ajax_lookup endpoint — silently bypassing the restriction. This issue has been patched in version 0.25.1.","severity":{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-09","score":0.00279,"percentile":0.20491,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":true,"fix_available":true},"cwes":["CWE-862"],"published":"2026-05-21T21:31:40Z","modified":"2026-10-28T02:31:00Z","exploits":[{"source":"pocgithub","id":"rootdirective-sec/CVE-2026-46645-Analysis-Lab","title":"rootdirective-sec/CVE-2026-46645-Analysis-Lab","date":"2026-06-12","url":"https://github.com/rootdirective-sec/CVE-2026-46645-Analysis-Lab"}],"fixes":[{"ecosystem":"PyPI","package":"sqladmin","fixed_in":["0.25.1"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"sqladmin","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"0.25.0"},{"fixed":"0.25.1"}]}]},{"source":"osv","ecosystem":"PyPI","package":"sqladmin","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.25.1"}]}],"versions":["0.0.0","0.1.0","0.1.1","0.1.10","0.1.11","0.1.12","0.1.2","0.1.3","0.1.4","0.1.5","0.1.6","0.1.7","0.1.8","0.1.9","0.10.0","0.10.1","0.10.2","0.10.3","0.11.0","0.12.0","0.13.0","0.14.0","0.14.1","0.15.0","0.15.1","0.15.2","0.16.0","0.16.1","0.17.0","0.18.0","0.19.0","0.2.0","0.2.1","0.20.0","0.20.1","0.21.0","0.22.0","0.23.0","0.24.0","0.25.0","0.3.0","0.4.0","0.5.0","0.6.0","0.6.1","0.7.0","0.8.0","0.9.0"]},{"source":"osv","ecosystem":"PyPI","package":"sqladmin","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.25.1"}]}],"versions":["0.0.0","0.1.0","0.1.1","0.1.10","0.1.11","0.1.12","0.1.2","0.1.3","0.1.4","0.1.5","0.1.6","0.1.7","0.1.8","0.1.9","0.10.0","0.10.1","0.10.2","0.10.3","0.11.0","0.12.0","0.13.0","0.14.0","0.14.1","0.15.0","0.15.1","0.15.2","0.16.0","0.16.1","0.17.0","0.18.0","0.19.0","0.2.0","0.2.1","0.20.0","0.20.1","0.21.0","0.22.0","0.23.0","0.24.0","0.25.0","0.3.0","0.4.0","0.5.0","0.6.0","0.6.1","0.7.0","0.8.0","0.9.0"]}],"products":[{"vendor":"smithyhq","product":"sqladmin"}],"references":[{"url":"https://github.com/smithyhq/sqladmin/security/advisories/GHSA-54mc-gghv-4cfj","tags":["x_refsource_CONFIRM","advisory","web"]},{"url":"https://github.com/smithyhq/sqladmin/pull/1035","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/smithyhq/sqladmin/commit/b0d3a19fb9b074a9ed243de46930108375dfbb98","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/smithyhq/sqladmin/releases/tag/0.25.1","tags":["x_refsource_MISC","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-46645","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-54mc-gghv-4cfj","tags":["advisory"]},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/46xxx/CVE-2026-46645.json","tags":["advisory"]},{"url":"https://github.com/smithyhq/sqladmin","tags":["package"]},{"url":"https://pypi.org/project/sqladmin","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-46645","title":"SQLAdmin: Authorization Bypass on `ajax_lookup`","description":"SQLAdmin is a flexible Admin interface for SQLAlchemy models. Prior to version 0.25.1, the ajax_lookup endpoint in application.py bypasses the is_accessible() access control check that all other endpoints enforce. If a developer restricts model access by overriding is_accessible(), an authenticated user can still query that model's data through the ajax_lookup endpoint — silently bypassing the restriction. This issue has been patched in version 0.25.1.","status":"published","published":"2026-06-10T22:23:57.397Z","modified":"2026-06-11T16:14:04.832Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","level":"medium","assessor":"cna"}],"cwes":["CWE-862"],"updated_at":"2026-11-02T13:47:06.353366Z"}],"euvd":[{"id":"EUVD-2026-36168","description":"SQLAdmin is a flexible Admin interface for SQLAlchemy models. Prior to version 0.25.1, the ajax_lookup endpoint in application.py bypasses the is_accessible() access control check that all other endpoints enforce. If a developer restricts model access by overriding is_accessible(), an authenticated user can still query that model's data through the ajax_lookup endpoint — silently bypassing the restriction. This issue has been patched in version 0.25.1.","status":"published","published":"2026-06-10T22:23:57Z","modified":"2026-06-11T16:14:04Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","level":"medium"}],"updated_at":"2026-11-02T18:20:44.061211Z"}],"ghsa":[{"id":"GHSA-54mc-gghv-4cfj","title":"SQLAdmin: Authorization Bypass on `ajax_lookup`","description":"### Impact\n\nThe `ajax_lookup` endpoint in `application.py` bypasses the `is_accessible()` access control check that all other endpoints enforce.\n\nIf a developer restricts model access by overriding `is_accessible()`, an authenticated user can still query that model's data through the `ajax_lookup` endpoint — silently bypassing the restriction.\n\n**Affected endpoint:**\n\n`GET /{identity}/ajax/lookup?name=\u003cfield\u003e\u0026term=\u003cquery\u003e`\n\n**All other endpoints enforce both checks:**\n\n| Endpoint | `@login_required` | `is_accessible()` |\n|---|---|---|\n| `list` | ✓ | ✓ |\n| `create` | ✓ | ✓ |\n| `edit` | ✓ | ✓ |\n| `delete` | ✓ | ✓ |\n| `details` | ✓ | ✓ |\n| `export` | ✓ | ✓ |\n| `ajax_lookup` (before fix) | ✗ | ✗ |\n| `ajax_lookup` (after fix) | ✓ | ✓ |\n\nNote: before this fix, `ajax_lookup` also lacked the `@login_required` decorator — unauthenticated users could query it directly. That was addressed in #1035. This report covers the remaining gap: authenticated but unauthorized users.\n\n### Patches\n\nTwo changes were made to `ajax_lookup`:\n\n1. Replaced the hand-rolled authentication check added in #1035 with the standard `@login_required` decorator used by all other endpoints.\n2. Added the missing `is_accessible(request)` check, raising `HTTP 403` when it returns `False`.\n\n### Workarounds\n\nNone. Developers relying on `is_accessible()` to restrict model visibility are exposed regardless of what other access controls are in place.","status":"published","published":"2026-05-21T21:31:40Z","modified":"2026-06-11T14:06:18Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","level":"medium"}],"cwes":["CWE-862"],"updated_at":"2026-11-02T14:40:26.12116Z"}],"nvd":[{"id":"CVE-2026-46645","description":"SQLAdmin is a flexible Admin interface for SQLAlchemy models. Prior to version 0.25.1, the ajax_lookup endpoint in application.py bypasses the is_accessible() access control check that all other endpoints enforce. If a developer restricts model access by overriding is_accessible(), an authenticated user can still query that model's data through the ajax_lookup endpoint — silently bypassing the restriction. This issue has been patched in version 0.25.1.","status":"published","published":"2026-06-10T23:16:47.31Z","modified":"2026-07-23T09:10:00.113Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","level":"medium","assessor":"secondary"}],"cwes":["CWE-862"],"updated_at":"2026-11-02T14:12:23.485267Z"}],"osv":[{"id":"CVE-2026-46645","title":"SQLAdmin: Authorization Bypass on `ajax_lookup`","description":"SQLAdmin is a flexible Admin interface for SQLAlchemy models. Prior to version 0.25.1, the ajax_lookup endpoint in application.py bypasses the is_accessible() access control check that all other endpoints enforce. If a developer restricts model access by overriding is_accessible(), an authenticated user can still query that model's data through the ajax_lookup endpoint — silently bypassing the restriction. This issue has been patched in version 0.25.1.","status":"published","published":"2026-06-10T22:23:57.397Z","modified":"2026-10-28T02:31:00.737598066Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","level":"medium"}],"cwes":["CWE-862"],"updated_at":"2026-11-02T15:45:06.231145Z"},{"id":"GHSA-54mc-gghv-4cfj","title":"SQLAdmin: Authorization Bypass on `ajax_lookup`","description":"### Impact\n\nThe `ajax_lookup` endpoint in `application.py` bypasses the `is_accessible()` access control check that all other endpoints enforce.\n\nIf a developer restricts model access by overriding `is_accessible()`, an authenticated user can still query that model's data through the `ajax_lookup` endpoint — silently bypassing the restriction.\n\n**Affected endpoint:**\n\n`GET /{identity}/ajax/lookup?name=\u003cfield\u003e\u0026term=\u003cquery\u003e`\n\n**All other endpoints enforce both checks:**\n\n| Endpoint | `@login_required` | `is_accessible()` |\n|---|---|---|\n| `list` | ✓ | ✓ |\n| `create` | ✓ | ✓ |\n| `edit` | ✓ | ✓ |\n| `delete` | ✓ | ✓ |\n| `details` | ✓ | ✓ |\n| `export` | ✓ | ✓ |\n| `ajax_lookup` (before fix) | ✗ | ✗ |\n| `ajax_lookup` (after fix) | ✓ | ✓ |\n\nNote: before this fix, `ajax_lookup` also lacked the `@login_required` decorator — unauthenticated users could query it directly. That was addressed in #1035. This report covers the remaining gap: authenticated but unauthorized users.\n\n### Patches\n\nTwo changes were made to `ajax_lookup`:\n\n1. Replaced the hand-rolled authentication check added in #1035 with the standard `@login_required` decorator used by all other endpoints.\n2. Added the missing `is_accessible(request)` check, raising `HTTP 403` when it returns `False`.\n\n### Workarounds\n\nNone. Developers relying on `is_accessible()` to restrict model visibility are exposed regardless of what other access controls are in place.","status":"published","published":"2026-05-21T21:31:40Z","modified":"2026-07-13T16:42:34.47062094Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","level":"medium"}],"cwes":["CWE-862"],"updated_at":"2026-11-02T15:46:37.864461Z"},{"id":"PYSEC-2026-3073","title":"SQLAdmin: Authorization Bypass on `ajax_lookup`","description":"### Impact\n\nThe `ajax_lookup` endpoint in `application.py` bypasses the `is_accessible()` access control check that all other endpoints enforce.\n\nIf a developer restricts model access by overriding `is_accessible()`, an authenticated user can still query that model's data through the `ajax_lookup` endpoint — silently bypassing the restriction.\n\n**Affected endpoint:**\n\n`GET /{identity}/ajax/lookup?name=\u003cfield\u003e\u0026term=\u003cquery\u003e`\n\n**All other endpoints enforce both checks:**\n\n| Endpoint | `@login_required` | `is_accessible()` |\n|---|---|---|\n| `list` | ✓ | ✓ |\n| `create` | ✓ | ✓ |\n| `edit` | ✓ | ✓ |\n| `delete` | ✓ | ✓ |\n| `details` | ✓ | ✓ |\n| `export` | ✓ | ✓ |\n| `ajax_lookup` (before fix) | ✗ | ✗ |\n| `ajax_lookup` (after fix) | ✓ | ✓ |\n\nNote: before this fix, `ajax_lookup` also lacked the `@login_required` decorator — unauthenticated users could query it directly. That was addressed in #1035. This report covers the remaining gap: authenticated but unauthorized users.\n\n### Patches\n\nTwo changes were made to `ajax_lookup`:\n\n1. Replaced the hand-rolled authentication check added in #1035 with the standard `@login_required` decorator used by all other endpoints.\n2. Added the missing `is_accessible(request)` check, raising `HTTP 403` when it returns `False`.\n\n### Workarounds\n\nNone. Developers relying on `is_accessible()` to restrict model visibility are exposed regardless of what other access controls are in place.","status":"published","published":"2026-07-13T15:19:11.118692Z","modified":"2026-07-13T16:33:12.404033375Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","level":"medium"}],"updated_at":"2026-11-02T15:52:56.429374Z"}]}}
