From 1838670e314e78891186fdec5077855544189bbc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur <eldy@destailleur.fr> Date: Wed, 7 Dec 2016 19:02:39 +0100 Subject: [PATCH] Fix several security holes on api when used by external users --- .../action/class/api_agendaevents.class.php | 12 +++++-- .../comm/propal/class/api_proposals.class.php | 4 ++- .../class/api_deprecated_commande.class.php | 1 + htdocs/commande/class/api_orders.class.php | 4 ++- .../class/api_deprecated_invoice.class.php | 1 + .../facture/class/api_invoices.class.php | 15 +++++---- .../class/api_expensereports.class.php | 7 +---- .../class/api_supplier_invoices.class.php | 4 ++- htdocs/projet/class/api_projects.class.php | 4 ++- htdocs/projet/class/api_tasks.class.php | 4 ++- htdocs/societe/class/api_contacts.class.php | 31 +++++++++---------- .../class/api_deprecated_thirdparty.class.php | 1 + .../societe/class/api_thirdparties.class.php | 14 +++++---- 13 files changed, 60 insertions(+), 42 deletions(-) diff --git a/htdocs/comm/action/class/api_agendaevents.class.php b/htdocs/comm/action/class/api_agendaevents.class.php index 931283b0ab0..7d66dccdd63 100644 --- a/htdocs/comm/action/class/api_agendaevents.class.php +++ b/htdocs/comm/action/class/api_agendaevents.class.php @@ -102,13 +102,19 @@ class AgendaEvents extends DolibarrApi $obj_ret = array(); - // case of external user, $societe param is ignored and replaced by user's socid - //$socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $societe; - + // case of external user + $socid = 0; + if (! empty(DolibarrApiAccess::$user->societe_id)) $socid = DolibarrApiAccess::$user->societe_id; + + // If the internal user must only see his customers, force searching by him + $search_sale = 0; + if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; + $sql = "SELECT t.id as rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."actioncomm as t"; $sql.= ' WHERE t.entity IN ('.getEntity('agenda', 1).')'; if ($user_ids) $sql.=" AND t.fk_user_action IN (".$user_ids.")"; + if ($socid > 0) $sql.= " AND t.fk_soc = ".$socid; // Insert sale filter if ($search_sale > 0) { diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index b4a15c2aa97..6ceac37a535 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -97,10 +97,12 @@ class Proposals extends DolibarrApi global $db, $conf; $obj_ret = array(); - // case of external user, $thirdpartyid param is ignored and replaced by user's socid + + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; // If the internal user must only see his customers, force searching by him + $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; $sql = "SELECT t.rowid"; diff --git a/htdocs/commande/class/api_deprecated_commande.class.php b/htdocs/commande/class/api_deprecated_commande.class.php index f5d799dd477..60c8c7f4aa8 100644 --- a/htdocs/commande/class/api_deprecated_commande.class.php +++ b/htdocs/commande/class/api_deprecated_commande.class.php @@ -115,6 +115,7 @@ class CommandeApi extends DolibarrApi $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $societe; // If the internal user must only see his customers, force searching by him + $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; $sql = "SELECT s.rowid"; diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index cc186367588..984ef5e6f43 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -101,10 +101,12 @@ class Orders extends DolibarrApi global $db, $conf; $obj_ret = array(); - // case of external user, $thirdpartyid param is ignored and replaced by user's socid + + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; // If the internal user must only see his customers, force searching by him + $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; $sql = "SELECT t.rowid"; diff --git a/htdocs/compta/facture/class/api_deprecated_invoice.class.php b/htdocs/compta/facture/class/api_deprecated_invoice.class.php index b87bb2e9dc0..7dd8a7ee6bc 100644 --- a/htdocs/compta/facture/class/api_deprecated_invoice.class.php +++ b/htdocs/compta/facture/class/api_deprecated_invoice.class.php @@ -111,6 +111,7 @@ class InvoiceApi extends DolibarrApi $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $socid; // If the internal user must only see his customers, force searching by him + $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; $sql = "SELECT s.rowid"; diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index 888c05bff26..ddbae55f0ef 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -98,21 +98,24 @@ class Invoices extends DolibarrApi global $db, $conf; $obj_ret = array(); - // case of external user, $thirdpartyid param is ignored and replaced by user's socid + + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; - + // If the internal user must only see his customers, force searching by him - if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; + $search_sale = 0; + if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; $sql = "SELECT t.rowid"; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) $sql.= " FROM ".MAIN_DB_PREFIX."facture as t"; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale $sql.= ' WHERE t.entity IN ('.getEntity('facture', 1).')'; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")"; + if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale // Filter by status diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php index bf07089b71b..cb506d32cdf 100644 --- a/htdocs/expensereport/class/api_expensereports.class.php +++ b/htdocs/expensereport/class/api_expensereports.class.php @@ -101,17 +101,12 @@ class ExpenseReports extends DolibarrApi // case of external user, $societe param is ignored and replaced by user's socid //$socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $societe; - + $sql = "SELECT t.rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as t"; $sql.= ' WHERE t.entity IN ('.getEntity('expensereport', 1).')'; if ($user_ids) $sql.=" AND t.fk_user_author IN (".$user_ids.")"; - // Insert sale filter - if ($search_sale > 0) - { - $sql .= " AND sc.fk_user = ".$search_sale; - } // Add sql filters if ($sqlfilters) { diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 660e64147ed..2348abfdc48 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -99,10 +99,12 @@ class SupplierInvoices extends DolibarrApi global $db, $conf; $obj_ret = array(); - // case of external user, $thirdpartyid param is ignored and replaced by user's socid + + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; // If the internal user must only see his customers, force searching by him + $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; $sql = "SELECT t.rowid"; diff --git a/htdocs/projet/class/api_projects.class.php b/htdocs/projet/class/api_projects.class.php index 2b5ee92d878..78e7954a097 100644 --- a/htdocs/projet/class/api_projects.class.php +++ b/htdocs/projet/class/api_projects.class.php @@ -102,10 +102,12 @@ class Projects extends DolibarrApi global $db, $conf; $obj_ret = array(); - // case of external user, $thirdpartyid param is ignored and replaced by user's socid + + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; // If the internal user must only see his customers, force searching by him + $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; $sql = "SELECT t.rowid"; diff --git a/htdocs/projet/class/api_tasks.class.php b/htdocs/projet/class/api_tasks.class.php index c88850ca403..1678e43328f 100644 --- a/htdocs/projet/class/api_tasks.class.php +++ b/htdocs/projet/class/api_tasks.class.php @@ -109,10 +109,12 @@ class Tasks extends DolibarrApi global $db, $conf; $obj_ret = array(); - // case of external user, $thirdpartyid param is ignored and replaced by user's socid + + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; // If the internal user must only see his customers, force searching by him + $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; $sql = "SELECT t.rowid"; diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index 9f09f7f7408..da8e930a0ce 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -84,41 +84,40 @@ class Contacts extends DolibarrApi * * Get a list of contacts * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Limit for list - * @param int $page Page number - * @param int $socid ID of thirdparty to filter list - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" - * @return array Array of contact objects + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $thirdparty_ids Thirdparty ids to filter projects of. {@example '1' or '1,2,3'} {@pattern /^[0-9,]*$/i} + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" + * @return array Array of contact objects * * @throws RestException */ - function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $socid = 0, $sqlfilters = '') { + function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids = '', $sqlfilters = '') { global $db, $conf; $obj_ret = array(); - if (!$socid) - { - $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : ''; - } + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid + $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; // If the internal user must only see his customers, force searching by him - if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) + $search_sale = 0; + if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; $sql = "SELECT t.rowid"; $sql.= " FROM " . MAIN_DB_PREFIX . "socpeople as t"; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) { + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) { // We need this table joined to the select in order to filter by sale $sql.= ", " . MAIN_DB_PREFIX . "societe_commerciaux as sc"; } $sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON t.fk_soc = s.rowid"; $sql.= ' WHERE t.entity IN (' . getEntity('socpeople', 1) . ')'; - if ($socid) $sql.= " AND t.fk_soc = " . $socid; + if ($socids) $sql.= " AND t.fk_soc IN (" . $socids . ")"; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc"; // Join for the needed table to filter by sale diff --git a/htdocs/societe/class/api_deprecated_thirdparty.class.php b/htdocs/societe/class/api_deprecated_thirdparty.class.php index 6086f2366d8..8b0302f9c11 100644 --- a/htdocs/societe/class/api_deprecated_thirdparty.class.php +++ b/htdocs/societe/class/api_deprecated_thirdparty.class.php @@ -165,6 +165,7 @@ class ThirdpartyApi extends DolibarrApi $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : ''; // If the internal user must only see his customers, force searching by him + $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; $sql = "SELECT s.rowid"; diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index bc156b5cc4a..674d8abcf42 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -102,25 +102,27 @@ class Thirdparties extends DolibarrApi $obj_ret = array(); - $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : ''; + // case of external user, we force socids + $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : ''; // If the internal user must only see his customers, force searching by him - if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; + $search_sale = 0; + if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; $sql = "SELECT t.rowid"; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) $sql.= " FROM ".MAIN_DB_PREFIX."societe as t"; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale $sql.= ", ".MAIN_DB_PREFIX."c_stcomm as st"; $sql.= " WHERE t.fk_stcomm = st.id"; if ($mode == 1) $sql.= " AND t.client IN (1, 3)"; if ($mode == 2) $sql.= " AND t.client IN (2, 3)"; if ($mode == 3) $sql.= " AND t.client IN (0)"; $sql.= ' AND t.entity IN ('.getEntity('societe', 1).')'; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; //if ($email != NULL) $sql.= " AND s.email = \"".$email."\""; - if ($socid) $sql.= " AND t.rowid = ".$socid; + if ($socid) $sql.= " AND t.rowid IN (".$socids.")"; if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale // Insert sale filter if ($search_sale > 0) -- GitLab