| Title | aaPanel BaoTa < 11.8.0 SQL Injection |
|---|
| Description | Summary
`get_domain_status` concatenates `get.domains` using `split(“,”)` and `“‘,’”.join()` to form `name in (‘...’)`, and uses empty parameterization (`param=()`) with no placeholders. An attacker can use single-quote closure to inject SQL. This API returns `{domain: bool}`, where `false` indicates a domain match and `true` indicates no match, constituting a Boolean oracle. Since the backend uses SQLite, `randomblob()` can be used to create observable delays, enabling a time-based blind injection.
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/mod/project/domain/domainMod.py`
- Route: `POST /mod/domain/domain/get_domain_status` (authenticated via `comm.local()`)
- Backend: SQLite (`public.M(“domain”)` maps to the `domain` table in `site.db`/`default.db`)
- Prerequisite: The `domain` table must contain at least one valid domain name as a reference (this condition is typically met on production panels hosting websites).
Vulnerability Code
https://github.com/aaPanel/BaoTa/blob/main/mod/project/domain/domainMod.py#L88-L91
this is source code:
def get_domain_status(self, get):
domains = get.domains.split(",")
domain_string = "','".join(domains)
data = public.M("domain").where("name in ('{}')".format(domain_string), ()).select()
Analysis:
# domainMod.py:88-91 — domains are joined and formatted directly, but param=() is empty!
domains = get.domains.split(“,”)
domain_string = “‘,’”.join(domains)
data = public.M(“domain”).where(“name in (‘{}’)”.format(domain_string), ()).select()
Prerequisites
1. Valid admin credentials for the panel
2. An `x-http-token` bound to the session
3. A domain that can be resolved as an oracle in the `domain` table
PoC, Proof, and original email correspondence with the vendor's maintainer, please see the reference URL:https://gist.github.com/zuesdevil/ec002a1540dd30d5e0d4a349b9f6fcbf |
|---|
| Source | ⚠️ https://gist.github.com/zuesdevil/ec002a1540dd30d5e0d4a349b9f6fcbf |
|---|
| User | zuesdevil (UID 100502) |
|---|
| Submission | 08/11/2026 12:07 (2 months ago) |
|---|
| Moderation | 09/27/2026 13:05 (2 months later) |
|---|
| Status | Accepted |
|---|
| VulDB entry | 410881 [aaPanel BaoTa up to 11.8.0 Domain domainMod.py get_domain_status get sql injection] |
|---|
| Points | 20 |
|---|