From ade854a469dbe756572927ca0f24f9e1c5368347 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 18 Jul 2022 16:48:53 +0200 Subject: [PATCH 1/3] FIX security breach if we have same ref number in multiple entities --- htdocs/comm/propal/class/propal.class.php | 5 ++- htdocs/core/lib/signature.lib.php | 7 ++-- htdocs/public/onlinesign/newonlinesign.php | 42 +++++++++------------- 3 files changed, 24 insertions(+), 30 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index c18e0e7a6df..37d6c96a6e5 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -1452,6 +1452,8 @@ class Propal extends CommonObject */ public function fetch($rowid, $ref = '', $ref_ext = '') { + global $conf; + $sql = "SELECT p.rowid, p.ref, p.entity, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc"; $sql .= ", p.total_ttc, p.total_tva, p.localtax1, p.localtax2, p.total_ht"; $sql .= ", p.datec"; @@ -1490,9 +1492,10 @@ class Propal extends CommonObject $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON p.fk_incoterms = i.rowid'; if ($ref) { - $sql .= " WHERE p.entity IN (".getEntity('propal').")"; // Dont't use entity if you use rowid + $sql .= " WHERE p.entity = ".(int) $conf->entity; // Check only the current entity because we may have the same reference in several entities $sql .= " AND p.ref='".$this->db->escape($ref)."'"; } else { + // Dont't use entity if you use rowid $sql .= " WHERE p.rowid = ".((int) $rowid); } diff --git a/htdocs/core/lib/signature.lib.php b/htdocs/core/lib/signature.lib.php index c57807800d7..5c6e8a08eed 100644 --- a/htdocs/core/lib/signature.lib.php +++ b/htdocs/core/lib/signature.lib.php @@ -59,7 +59,8 @@ function showOnlineSignatureUrl($type, $ref) */ function getOnlineSignatureUrl($mode, $type, $ref = '', $localorexternal = 1) { - global $conf, $db, $langs, $dolibarr_main_url_root; + global $conf, $dolibarr_main_url_root; + global $object; $ref = str_replace(' ', '', $ref); $out = ''; @@ -90,7 +91,7 @@ function getOnlineSignatureUrl($mode, $type, $ref = '', $localorexternal = 1) if ($mode == 1) { $out .= "hash('".$securekeyseed."' + '".$type."' + proposal_ref)"; } else { - $out .= '&securekey='.dol_hash($securekeyseed.$type.$ref, '0'); + $out .= '&securekey='.dol_hash($securekeyseed.$type.$ref.$object->entity, '0'); } /* if ($mode == 1) { @@ -120,7 +121,7 @@ function getOnlineSignatureUrl($mode, $type, $ref = '', $localorexternal = 1) // For multicompany if (!empty($out) && !empty($conf->multicompany->enabled)) { - $out .= "&entity=".$conf->entity; // Check the entity because we may have the same reference in several entities + $out .= "&entity=".$object->entity; // Check the entity of object because we may have the same reference in several entities } return $out; diff --git a/htdocs/public/onlinesign/newonlinesign.php b/htdocs/public/onlinesign/newonlinesign.php index d1020dc2c1d..06332d5867a 100644 --- a/htdocs/public/onlinesign/newonlinesign.php +++ b/htdocs/public/onlinesign/newonlinesign.php @@ -139,7 +139,7 @@ if ($source == 'proposal') { $securekeyseed = $conf->global->PROPOSAL_ONLINE_SIGNATURE_SECURITY_TOKEN; } -if (!dol_verifyHash($securekeyseed.$type.$ref, $SECUREKEY, '0')) { +if (!dol_verifyHash($securekeyseed.$type.$ref.$object->entity, $SECUREKEY, '0')) { http_response_code(403); print 'Bad value for securitykey. Value provided '.dol_escape_htmltag($SECUREKEY).' does not match expected value for ref='.dol_escape_htmltag($ref); exit(-1); @@ -288,18 +288,8 @@ $error = 0; // Signature on commercial proposal if ($source == 'proposal') { $found = true; - $langs->load("proposal"); - require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; - - $proposal = new Propal($db); - $result = $proposal->fetch('', $ref); - if ($result <= 0) { - $mesg = $proposal->error; - $error++; - } else { - $result = $proposal->fetch_thirdparty($proposal->socid); - } + $result = $object->fetch_thirdparty($object->socid); // Creditor @@ -315,39 +305,39 @@ if ($source == 'proposal') { print ''.$langs->trans("ThirdParty"); print ''; print img_picto('', 'company', 'class="pictofixedwidth"'); - print ''.$proposal->thirdparty->name.''; + print ''.$object->thirdparty->name.''; print ''."\n"; // Amount print ''.$langs->trans("Amount"); print ''; - print ''.price($proposal->total_ttc, 0, $langs, 1, -1, -1, $conf->currency).''; + print ''.price($object->total_ttc, 0, $langs, 1, -1, -1, $conf->currency).''; print ''."\n"; // Object - $text = ''.$langs->trans("SignatureProposalRef", $proposal->ref).''; + $text = ''.$langs->trans("SignatureProposalRef", $object->ref).''; print ''.$langs->trans("Designation"); print ''.$text; - if ($proposal->status == $proposal::STATUS_VALIDATED) { - $directdownloadlink = $proposal->getLastMainDocLink('proposal'); + if ($object->status == $object::STATUS_VALIDATED) { + $directdownloadlink = $object->getLastMainDocLink('proposal'); if ($directdownloadlink) { print '
'; - print img_mime($proposal->last_main_doc, ''); + print img_mime($object->last_main_doc, ''); print $langs->trans("DownloadDocument").''; } } else { - $last_main_doc_file = $proposal->last_main_doc; + $last_main_doc_file = $object->last_main_doc; - if ($proposal->status == $proposal::STATUS_NOTSIGNED) { - $directdownloadlink = $proposal->getLastMainDocLink('proposal'); + if ($object->status == $object::STATUS_NOTSIGNED) { + $directdownloadlink = $object->getLastMainDocLink('proposal'); if ($directdownloadlink) { print '
'; - print img_mime($proposal->last_main_doc, ''); + print img_mime($object->last_main_doc, ''); print $langs->trans("DownloadDocument").''; } - } elseif ($proposal->status == $proposal::STATUS_SIGNED || $proposal->status == $proposal::STATUS_BILLED) { + } elseif ($object->status == $object::STATUS_SIGNED || $object->status == $object::STATUS_BILLED) { if (preg_match('/_signed-(\d+)/', $last_main_doc_file)) { // If the last main doc has been signed $last_main_doc_file_not_signed = preg_replace('/_signed-(\d+)/', '', $last_main_doc_file); @@ -355,10 +345,10 @@ if ($source == 'proposal') { $datefilenotsigned = dol_filemtime($last_main_doc_file_not_signed); if (empty($datefilenotsigned) || $datefilesigned > $datefilenotsigned) { - $directdownloadlink = $proposal->getLastMainDocLink('proposal'); + $directdownloadlink = $object->getLastMainDocLink('proposal'); if ($directdownloadlink) { print '
'; - print img_mime($proposal->last_main_doc, ''); + print img_mime($object->last_main_doc, ''); print $langs->trans("DownloadDocument").''; } } @@ -367,7 +357,7 @@ if ($source == 'proposal') { } print ''; - print ''; + print ''; print ''."\n"; // TODO Add link to download PDF (similar code than for invoice) From 7db5f7eb1ce7fc996379dd95e3f60c0bcc749b20 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 18 Jul 2022 19:26:13 +0200 Subject: [PATCH 2/3] FIX regression + add $forceentity parameter --- htdocs/comm/propal/class/propal.class.php | 21 ++++++++++++--------- htdocs/core/lib/signature.lib.php | 2 +- htdocs/public/onlinesign/newonlinesign.php | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 37d6c96a6e5..5b91caa2673 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -1445,15 +1445,14 @@ class Propal extends CommonObject /** * Load a proposal from database. Get also lines. * - * @param int $rowid id of object to load - * @param string $ref Ref of proposal - * @param string $ref_ext Ref ext of proposal - * @return int >0 if OK, <0 if KO + * @param int $rowid id of object to load + * @param string $ref Ref of proposal + * @param string $ref_ext Ref ext of proposal + * @param int $forceentity Entity id to force + * @return int >0 if OK, <0 if KO */ - public function fetch($rowid, $ref = '', $ref_ext = '') + public function fetch($rowid, $ref = '', $ref_ext = '', $forceentity = 0) { - global $conf; - $sql = "SELECT p.rowid, p.ref, p.entity, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc"; $sql .= ", p.total_ttc, p.total_tva, p.localtax1, p.localtax2, p.total_ht"; $sql .= ", p.datec"; @@ -1491,8 +1490,12 @@ class Propal extends CommonObject $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_input_reason as dr ON p.fk_input_reason = dr.rowid'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON p.fk_incoterms = i.rowid'; - if ($ref) { - $sql .= " WHERE p.entity = ".(int) $conf->entity; // Check only the current entity because we may have the same reference in several entities + if (!empty($ref)) { + if (!empty($forceentity)) { + $sql .= " WHERE p.entity = ".(int) $forceentity; // Check only the current entity because we may have the same reference in several entities + } else { + $sql .= " WHERE p.entity IN (".getEntity('propal').")"; + } $sql .= " AND p.ref='".$this->db->escape($ref)."'"; } else { // Dont't use entity if you use rowid diff --git a/htdocs/core/lib/signature.lib.php b/htdocs/core/lib/signature.lib.php index 5c6e8a08eed..6a8d824872d 100644 --- a/htdocs/core/lib/signature.lib.php +++ b/htdocs/core/lib/signature.lib.php @@ -26,7 +26,7 @@ */ function showOnlineSignatureUrl($type, $ref) { - global $conf, $langs; + global $langs; // Load translation files required by the page $langs->loadLangs(array("payment", "paybox")); diff --git a/htdocs/public/onlinesign/newonlinesign.php b/htdocs/public/onlinesign/newonlinesign.php index 06332d5867a..9ebea80aeb3 100644 --- a/htdocs/public/onlinesign/newonlinesign.php +++ b/htdocs/public/onlinesign/newonlinesign.php @@ -126,7 +126,7 @@ $creditor = $mysoc->name; $type = $source; if ($source == 'proposal') { $object = new Propal($db); - $object->fetch(0, $ref); + $object->fetch(0, $ref, '', $entity); } else { accessforbidden('Bad value for source'); exit; From 888328b03b5c9a464490f48b181c7829fc4ec46f Mon Sep 17 00:00:00 2001 From: comaiteseb <109105553+comaiteseb@users.noreply.github.com> Date: Tue, 19 Jul 2022 15:31:29 +0200 Subject: [PATCH 3/3] FIX issue Dolibarr#21495 for v15 FIX #21495 Error when calculate the date when AGENDA_EXPORT_FIX_TZ is set. The resulting date is 1969-12-31 --- htdocs/comm/action/class/actioncomm.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index a5c8a11ade0..627855a94e8 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -2065,8 +2065,8 @@ class ActionComm extends CommonObject } if (!empty($conf->global->AGENDA_EXPORT_FIX_TZ)) { - $timestampStart = - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); - $timestampEnd = - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); + $timestampStart = $timestampStart - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); + $timestampEnd = $timestampEnd - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); } $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));