From 60b0f3666d84614320d24b85b179cad5cf891488 Mon Sep 17 00:00:00 2001 From: Elizabeth Date: Mon, 29 Jun 2020 02:54:16 +0100 Subject: [PATCH 1/4] begin work on csrf fixes --- interface/main/main_screen.php | 3 +++ interface/patient_file/letter.php | 9 +++++++++ library/sanitize.inc.php | 29 +++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/interface/main/main_screen.php b/interface/main/main_screen.php index e2639250d..e27f5dbba 100644 --- a/interface/main/main_screen.php +++ b/interface/main/main_screen.php @@ -41,6 +41,9 @@ session_regenerate_id(false); } +//generate csrf token +$_SESSION['token'] = generateCsrfToken(); + $_SESSION["encounter"] = ''; // Fetch the password expiration date diff --git a/interface/patient_file/letter.php b/interface/patient_file/letter.php index f3c4cd232..c009a0534 100644 --- a/interface/patient_file/letter.php +++ b/interface/patient_file/letter.php @@ -90,6 +90,14 @@ $alertmsg = ''; // anything here pops up in an alert box +if (!empty($_POST)) { + if (!isset($_POST['token'])) { + error_log('WARNING: A Post detected with not csrf token found'); + die('Authentication failed.'); + } else if (!hash_equals(hash_hmac('sha256', '/letter.php.theform', $_SESSION['token']), $_POST['token'])) { + die('Authentication failed.'); + } +} // If the Generate button was clicked... if ($_POST['formaction']=="generate") { @@ -430,6 +438,7 @@ function insertAtCursor(myField, myValue) {
+

diff --git a/library/sanitize.inc.php b/library/sanitize.inc.php index f61283315..c60f84397 100644 --- a/library/sanitize.inc.php +++ b/library/sanitize.inc.php @@ -55,5 +55,34 @@ function image_has_right_size($size) { return $size < 20971520; } +// Generate csrf token for authentication +function generateCsrfToken() +{ + if (!extension_loaded('openssl')) { + error_log("ERROR: openssl extension not enabled, needed for proper functioning of LibreHealth"); + die("Error: Systems needs openssl."); + } + + $csrfToken = bin2hex(openssl_random_pseudo_bytes(32)); + + if (empty($csrfToken)) { + error_log("ERROR : Token generation failed"); + die("Error : Unable to correctly generate token"); + } + + return $csrfToken; +} + +// Function to verify a csrf token +function verifyCsrfToken($token) +{ + if (hash_equals($_SESSION['token'], $token)) { + return true; + } else { + error_log("WARNING : Malicious attempt encountered"); + return false; + } +} + ?> From 763382559cfd80f8389b5e83499f02abeedc0357 Mon Sep 17 00:00:00 2001 From: Maggie Negm Date: Thu, 2 Jul 2020 19:06:22 -0400 Subject: [PATCH 2/4] Created CsrfToken class --- interface/main/main_screen.php | 3 ++- interface/patient_file/letter.php | 2 +- library/CsrfToken.php | 35 +++++++++++++++++++++++++++++++ library/sanitize.inc.php | 30 -------------------------- 4 files changed, 38 insertions(+), 32 deletions(-) create mode 100644 library/CsrfToken.php diff --git a/interface/main/main_screen.php b/interface/main/main_screen.php index e27f5dbba..c91262a29 100644 --- a/interface/main/main_screen.php +++ b/interface/main/main_screen.php @@ -24,6 +24,7 @@ /* Include our required headers */ require_once('../globals.php'); require_once("$srcdir/formdata.inc.php"); +require_once("../../library/CsrfToken.php"); // Creates a new session id when load this outer frame // (allows creations of separate LibreHealth EHR frames to view patients concurrently @@ -42,7 +43,7 @@ } //generate csrf token -$_SESSION['token'] = generateCsrfToken(); +$_SESSION['token'] = CsrfToken::generateCsrfToken(); $_SESSION["encounter"] = ''; diff --git a/interface/patient_file/letter.php b/interface/patient_file/letter.php index c009a0534..b88ca03c9 100644 --- a/interface/patient_file/letter.php +++ b/interface/patient_file/letter.php @@ -92,7 +92,7 @@ if (!empty($_POST)) { if (!isset($_POST['token'])) { - error_log('WARNING: A Post detected with not csrf token found'); + error_log('WARNING: A POST request detected with no csrf token found'); die('Authentication failed.'); } else if (!hash_equals(hash_hmac('sha256', '/letter.php.theform', $_SESSION['token']), $_POST['token'])) { die('Authentication failed.'); diff --git a/library/CsrfToken.php b/library/CsrfToken.php new file mode 100644 index 000000000..d616d3e2a --- /dev/null +++ b/library/CsrfToken.php @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/library/sanitize.inc.php b/library/sanitize.inc.php index c60f84397..c63981780 100644 --- a/library/sanitize.inc.php +++ b/library/sanitize.inc.php @@ -55,34 +55,4 @@ function image_has_right_size($size) { return $size < 20971520; } -// Generate csrf token for authentication -function generateCsrfToken() -{ - if (!extension_loaded('openssl')) { - error_log("ERROR: openssl extension not enabled, needed for proper functioning of LibreHealth"); - die("Error: Systems needs openssl."); - } - - $csrfToken = bin2hex(openssl_random_pseudo_bytes(32)); - - if (empty($csrfToken)) { - error_log("ERROR : Token generation failed"); - die("Error : Unable to correctly generate token"); - } - - return $csrfToken; -} - -// Function to verify a csrf token -function verifyCsrfToken($token) -{ - if (hash_equals($_SESSION['token'], $token)) { - return true; - } else { - error_log("WARNING : Malicious attempt encountered"); - return false; - } -} - - ?> From a7102ca2ed309ce14f46c99ab05ab158efa1a94d Mon Sep 17 00:00:00 2001 From: elizabeth Date: Wed, 15 Jul 2020 16:03:08 +0100 Subject: [PATCH 3/4] fix remote code execution in on history and import template modules --- interface/billing/edi_history_main.php | 9 +++++++++ interface/billing/edih_view.php | 9 +++++++++ library/CsrfToken.php | 10 ++++++++++ patient_portal/import_template.php | 9 +++++++++ patient_portal/import_template_ui.php | 3 ++- 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/interface/billing/edi_history_main.php b/interface/billing/edi_history_main.php index 1e15f4de5..434de427f 100644 --- a/interface/billing/edi_history_main.php +++ b/interface/billing/edi_history_main.php @@ -70,6 +70,7 @@ require_once("$srcdir/edihistory/ibr_ack_read.php"); //dirname(__FILE__) . "/edihist/ibr_ack_read.php"); require_once("$srcdir/edihistory/ibr_uploads.php"); //dirname(__FILE__) . "/edihist/ibr_uploads.php"); require_once("$srcdir/edihistory/ibr_io.php"); //dirname(__FILE__) . "/edihist/ibr_io.php"); +require_once("../../library/CsrfToken.php"); // // php may output line endings if include files are utf-8 ob_clean(); @@ -100,6 +101,14 @@ */ if (strtolower($_SERVER['REQUEST_METHOD']) == 'post') { + if (!empty($_POST)) { + if (!isset($_POST['token'])) { + error_log('WARNING: A POST request detected with no csrf token found'); + die('Authentication failed.'); + } else if (!(CsrfToken::verifyCsrfToken($_POST['token'])) { + die('Authentication failed.'); + } + } // if ( isset($_POST['NewFiles']) ) { // process new files button clicked diff --git a/interface/billing/edih_view.php b/interface/billing/edih_view.php index dc76f7b7e..af5a45458 100644 --- a/interface/billing/edih_view.php +++ b/interface/billing/edih_view.php @@ -75,6 +75,7 @@ " /> + @@ -87,6 +88,7 @@ " /> + @@ -159,6 +161,7 @@ --> + " /> @@ -220,6 +223,7 @@ " /> + @@ -236,6 +240,7 @@ " /> + @@ -253,6 +258,7 @@ " /> + @@ -263,6 +269,7 @@ " /> + @@ -275,6 +282,7 @@ " /> + @@ -309,6 +317,7 @@ " /> " /> + diff --git a/library/CsrfToken.php b/library/CsrfToken.php index d616d3e2a..6210ef67a 100644 --- a/library/CsrfToken.php +++ b/library/CsrfToken.php @@ -30,6 +30,16 @@ function verifyCsrfToken($token) return false; } } + // Function to verify a csrf token using with second token + function verifyCsrfTokenAndCompareHash($secondToken) + { + if (hash_equals(hash_hmac('sha256', '/letter.php.theform', $_SESSION['token']), $_POST['token'])) { + return true; + } else { + error_log("WARNING : Malicious attempt encountered"); + return false; + } + } } ?> \ No newline at end of file diff --git a/patient_portal/import_template.php b/patient_portal/import_template.php index 8dace706c..2ade0db97 100644 --- a/patient_portal/import_template.php +++ b/patient_portal/import_template.php @@ -19,7 +19,16 @@ $sanitize_all_escapes=true; $fake_register_globals=false; require_once("../interface/globals.php"); +require_once("../library/CsrfToken.php"); +if (!empty($_POST)) { + if (!isset($_POST['token'])) { + error_log('WARNING: A POST request detected with no csrf token found'); + die('Authentication failed.'); + } else if (!(CsrfToken::verifyCsrfToken($_POST['token'])) { + die('Authentication failed.'); + } +} if($_POST['mode'] == 'get'){ echo file_get_contents($_POST['docid']); exit; diff --git a/patient_portal/import_template_ui.php b/patient_portal/import_template_ui.php index de651c248..c970b053a 100644 --- a/patient_portal/import_template_ui.php +++ b/patient_portal/import_template_ui.php @@ -120,7 +120,7 @@ function getDocument(docname, mode, content){ $.ajax({ type: "POST", url: liburl, - data: {docid: docname, mode: mode,content: content}, + data: {docid: docname, mode: mode,content: content, token: }, beforeSend: function(xhr){ console.log("Please wait..."+content); }, @@ -192,6 +192,7 @@ function getDocument(docname, mode, content){ + From 09b50aab14a8c778b562719b96d3a8f0b251cfd4 Mon Sep 17 00:00:00 2001 From: Ngai Elizabeth Date: Wed, 15 Jul 2020 17:18:00 +0100 Subject: [PATCH 4/4] Update CsrfToken.php --- library/CsrfToken.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/CsrfToken.php b/library/CsrfToken.php index 6210ef67a..e17abf6e5 100644 --- a/library/CsrfToken.php +++ b/library/CsrfToken.php @@ -31,9 +31,9 @@ function verifyCsrfToken($token) } } // Function to verify a csrf token using with second token - function verifyCsrfTokenAndCompareHash($secondToken) + function verifyCsrfTokenAndCompareHash($token, $secondToken) { - if (hash_equals(hash_hmac('sha256', '/letter.php.theform', $_SESSION['token']), $_POST['token'])) { + if (hash_equals(hash_hmac('sha256', $secondToken, $_SESSION['token']), $token) { return true; } else { error_log("WARNING : Malicious attempt encountered"); @@ -42,4 +42,4 @@ function verifyCsrfTokenAndCompareHash($secondToken) } } -?> \ No newline at end of file +?>