From 2cc0283d25895f0d983510a750fa50e3bafbf87e Mon Sep 17 00:00:00 2001 From: Paolo Date: Mon, 17 Jul 2023 12:04:26 +0200 Subject: [PATCH 1/3] Added new protected method replaceSQLDecryptionPassword to include/basis_db.class.php --- include/basis_db.class.php | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/include/basis_db.class.php b/include/basis_db.class.php index 36d1eddc7..c7d3b26dd 100644 --- a/include/basis_db.class.php +++ b/include/basis_db.class.php @@ -163,6 +163,43 @@ abstract class db extends basis return $rows; } + /** + * Replace the password names with the related passwords in a SQL string, to decrypt data from the DB + */ + protected function replaceSQLDecryptionPassword($sql) + { + $newSQL = null; + + // If the global constant CI_ENVIRONMENT is not defined then return a failure + if (!defined('CI_ENVIRONMENT')) return null; + + define('BASEPATH', 'LEGACY_WORKAROUND'); // little trick to load a CI config file + + // Tries to include the CI config file that contains password for the database encryption + // If the include fails then return a failure + if (!include_once(dirname(__FILE__).'/../application/config/'.CI_ENVIRONMENT.'/db_crypt.php')) return null; + + // Array that will contains all the DB decryption password + $decryptionPasswordsArray = array(); + // Array that will contains all the DB decryption password names + $decryptionPasswordNamesArray = array(); + + // For each password found in the config array + foreach ($config['encryption_passwords'] as $name => $password) + { + // Copy the password name using this template: '{$''}' + $decryptionPasswordArray[] = $password; + $decryptionPasswordNamesArray[] = '${'.$name.'}'; + } + + // Replace the password names with the password values + $newSQL = str_replace($decryptionPasswordNamesArray, $decryptionPasswordArray, $sql); + + // In case the replacement is a failure + if ($newSQL == '' || $newSQL == null) return null; + + return $newSQL; // OK + } } require_once(dirname(__FILE__).'/'.DB_SYSTEM.'.class.php'); From 75fb0f2d4af5d4dd2932e8cea4cda683e737ecc2 Mon Sep 17 00:00:00 2001 From: Paolo Date: Mon, 17 Jul 2023 12:06:37 +0200 Subject: [PATCH 2/3] - include/filter.class.php -> loadValues now calls the superclass protected method replaceSQLDecryptionPassword to replace password variables with their values - include/statistik.class.php -> loadData now calls the superclass protected method replaceSQLDecryptionPassword to replace password variables with their values - Added new functions hasSQLDecryption and isSQLDecryptionValid to include/functions.inc.php - Script vilesci/statistik/filter_details.php and vilesci/stammdaten/statistik_details.php now do not allow to store SQL strings that contain PostgreSQL decryption functions using a clear password --- include/filter.class.php | 4 ++- include/functions.inc.php | 24 ++++++++++++++++++ include/statistik.class.php | 3 +++ vilesci/stammdaten/statistik_details.php | 32 ++++++++++++++++-------- vilesci/statistik/filter_details.php | 13 ++++++++-- 5 files changed, 63 insertions(+), 13 deletions(-) diff --git a/include/filter.class.php b/include/filter.class.php index 3578d7dcf..8357c8eb4 100644 --- a/include/filter.class.php +++ b/include/filter.class.php @@ -230,9 +230,11 @@ class filter extends basis_db */ public function loadValues($sql, $valuename, $showvalue) { - $this->values = array(); + // In case a decryption function is used then perform password substitution + $sql = $this->replaceSQLDecryptionPassword($sql); + if($this->db_query($sql)) { while($row = $this->db_fetch_row()) diff --git a/include/functions.inc.php b/include/functions.inc.php index 7b3560dde..d27708ea9 100644 --- a/include/functions.inc.php +++ b/include/functions.inc.php @@ -1196,4 +1196,28 @@ function anzahlTage($date1, $date2) $diff = $date2_ts - $date1_ts; return round($diff / 86400); } + +/** + * Checks if the provided SQL string contains PostgreSQL functions to decrypt data, returns a boolean + */ +function hasSQLDecryption($sql) +{ + return stripos($sql, 'PGP_SYM_DECRYPT') !== false; +} + +/** + * Checks if the provided SQL string contains PostgreSQL functions to decrypt data, + * and if it is used a variable instead of a readable password. Returns a boolean + */ +function isSQLDecryptionValid($sql) +{ + // If the SQL string contains decryption functions and there are _no_ password variables + if (hasSQLDecryption($sql) && strpos($sql, '${') === false) + { + return false; // then return false + } + + return true; // in any other case return true +} + ?> diff --git a/include/statistik.class.php b/include/statistik.class.php index d8bea89f9..a72c8bbeb 100644 --- a/include/statistik.class.php +++ b/include/statistik.class.php @@ -514,6 +514,9 @@ class statistik extends basis_db $this->countRows=0; set_time_limit(120); + // In case a decryption function is used then perform password substitution + $this->sql = $this->replaceSQLDecryptionPassword($this->sql); + if($this->sql!='') { $sql = $this->sql; diff --git a/vilesci/stammdaten/statistik_details.php b/vilesci/stammdaten/statistik_details.php index 1ba840c02..8ad12dc0b 100644 --- a/vilesci/stammdaten/statistik_details.php +++ b/vilesci/stammdaten/statistik_details.php @@ -26,6 +26,7 @@ require_once('../../config/vilesci.config.inc.php'); require_once('../../include/statistik.class.php'); require_once('../../include/benutzerberechtigung.class.php'); require_once('../../include/berechtigung.class.php'); +require_once('../../include/functions.inc.php'); if(!$db = new basis_db()) { @@ -140,18 +141,29 @@ if(!$rechte->isBerechtigt('basis/statistik', null, 'suid')) $statistik->berechtigung_kurzbz = $berechtigung_kurzbz; $statistik->preferences = $preferences; - $success = $statistik->save(); + // Check if the SQL string contains functions to decrypt data and if there are + // variables to replace the value of the password (no clear password wanted!) + if (isSQLDecryptionValid($statistik->sql)) + { + $success = $statistik->save(); - if($success): + if($success): + ?> + Daten erfolgreich gespeichert + + + errormsg ?> + - Daten erfolgreich gespeichert - - - errormsg ?> - + preferences); diff --git a/vilesci/statistik/filter_details.php b/vilesci/statistik/filter_details.php index 8ff284b1f..c2f27d927 100644 --- a/vilesci/statistik/filter_details.php +++ b/vilesci/statistik/filter_details.php @@ -76,9 +76,18 @@ $filter->type = $_POST["type"]; $filter->htmlattr = $_POST["htmlattr"]; - if(!$filter->save()) + // Check if the SQL string contains functions to decrypt data and if there are + // variables to replace the value of the password (no clear password wanted!) + if (isSQLDecryptionValid($filter->sql)) { - $errorstr .= $filter->errormsg; + if (!$filter->save()) + { + $errorstr .= $filter->errormsg; + } + } + else + { + $errorstr .= 'It is not possible to store a SQL that contains clear passwords to decrypt data from the DB'; } $reloadstr .= "