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.
Affected endpoint:
GET /{identity}/ajax/lookup?name=<field>&term=<query>
All other endpoints enforce both checks:
| Endpoint | @login_required | is_accessible() |
|---|---|---|
| list | ✓ | ✓ |
| create | ✓ | ✓ |
| edit | ✓ | ✓ |
| delete | ✓ | ✓ |
| details | ✓ | ✓ |
| export | ✓ | ✓ |
| ajax_lookup (before fix) | ✗ | ✗ |
| ajax_lookup (after fix) | ✓ | ✓ |
Note: 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.
Two changes were made to ajax_lookup:
@login_required decorator used by all other endpoints.is_accessible(request) check, raising HTTP 403 when it returns False.None. Developers relying on is_accessible() to restrict model visibility are exposed regardless of what other access controls are in place.
{
"nvd_published_at": null,
"severity": "MODERATE",
"github_reviewed": true,
"cwe_ids": [
"CWE-862"
],
"github_reviewed_at": "2026-05-21T21:31:40Z"
}