| 标题 | aaPanel BaoTa < 11.8.0 SQL Injection |
|---|
| 描述 | Summary
When constructing the `WHERE` clause for the `getData` action of the `/data` endpoint, `get.log_type` is directly
`.format()` into the SQL, and `log_type` is not on the `GetWhere` whitelist. The `logs` table has 6 columns
(id, uid, username, type, log, addtime). An attacker can use `UNION SELECT` to align these 6 columns to achieve
data reflection, allowing them to read data from any table in the SQLite database being mapped (operation logs, login IPs, usernames, etc.)
Severity:High
CWE:CWE-89
The vendor maintainer has acknowledged the issue and has already implemented a fix; however, the patched version 11.8.1 has not yet been released.
Affected Versions and Components
- Product: Baota Linux Panel (https://github.com/aaPanel/BaoTa/)
- Process: `/www/server/panel/BT-Panel` (running as `root`, PID 10001)
- File: `/www/server/panel/class/data.py`
- Route: `POST /data`
- Backend: SQLite (panel database `data/db/*.db`; `public.M()` selects the database based on the mapping in `config/databases.json`)
- Number of Columns: The `logs` table exists and contains data
Vulnerability Code:
https://github.com/aaPanel/BaoTa/blob/main/class/data.py#L760-L781
this is source code:
if get.table == "logs" and logs_type:
where = " type = '{}' ".format(get.log_type)
if hasattr(get, 'search'):
search = get.search
if sys.version_info[0] == 2: get.search = get.search.encode('utf-8')
where, param = self.GetWhere(get.table, get.search)
if get.table == 'logs' and logs_type and search:
where = " type='{}' and ({})".format(get.log_type, where)
if get.table == 'backup':
where += " and type='{}'".format(int(get.type))
if get.table == 'sites' and get.search:
conditions = ''
if '_' in get.search:
get.search = str(get.search).replace("_", "/_")
conditions = " escape '/'"
pid = public.M('domain').where("name LIKE ?{}".format(conditions), ("%{}%".format(get.search),)).getField('pid')
if pid:
if where:
where += " or id=" + str(pid)
else:
where += "id=" + str(pid)
Analysis:
# data.py:761 — log_type is directly formatted into the WHERE clause; no whitelist
where = “ type = ‘{}’ ”.format(get.log_type)
# data.py:768 — Same issue
where = “ type=‘{}’ and ({})”.format(get.log_type, where)
# GetWhere only overrides `search`, not `log_type`
# Final result: db.where(where, param) → execute(sql, OPT_PARAM)
`get.log_type` is fully controllable—no escaping, no whitelisting, and no parameterization.
Prerequisites
1. Valid admin credentials for the dashboard
2. An `x-http-token` bound to the session
3. The `/data table=logs` table must be queryable
PoC, Proof, and original email correspondence with the vendor's maintainer, please see the reference URL:https://gist.github.com/zuesdevil/e9760c3329b739d37f3a9dc501881384 |
|---|
| 来源 | ⚠️ https://gist.github.com/zuesdevil/e9760c3329b739d37f3a9dc501881384 |
|---|
| 用户 | zuesdevil (UID 100502) |
|---|
| 提交 | 2026-08-11 11時47分 (2 月前) |
|---|
| 管理 | 2026-09-27 13時05分 (2 months later) |
|---|
| 状态 | 已接受 |
|---|
| VulDB条目 | 410880 [aaPanel BaoTa 直到 11.8.0 data.py getData log_type SQL注入] |
|---|
| 积分 | 20 |
|---|