N°3473 - security hardening

This commit is contained in:
bruno-ds
2021-02-24 16:46:23 +01:00
parent e1d644c33b
commit 9b7cd20d47
6 changed files with 64 additions and 17 deletions

View File

@@ -459,17 +459,21 @@ EOF
$sAttType = $aTargetAttCodes[$sTargetAttCode];
$sExtFieldAttCode = $sTargetAttCode;
}
if (is_a($sAttType, 'AttributeLinkedSet', true))
{
continue;
}
if (is_a($sAttType, 'AttributeFriendlyName', true))
{
continue;
}
if (is_a($sAttType, 'AttributeOneWayPassword', true))
{
continue;
$aForbidenAttType = [
'AttributeLinkedSet',
'AttributeFriendlyName',
'iAttributeNoGroupBy', //we cannot only use iAttributeNoGroupBy since this method is also used by the designer who do not have access to the classes' PHP reflection API. So the known classes has to be listed altogether
'AttributeOneWayPassword',
'AttributeEncryptedString',
'AttributePassword',
];
foreach ($aForbidenAttType as $sForbidenAttType) {
if (is_a($sAttType, $sForbidenAttType, true))
{
continue 2;
}
}
$sLabel = $this->oModelReflection->GetLabel($sClass, $sAttCode);

View File

@@ -446,8 +446,21 @@ class DisplayBlock
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, $aOrderBy, $aQueryParams);
}
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
switch($this->m_sStyle)
{
switch($this->m_sStyle) {
case 'list_search':
case 'list':
break;
default:
// N°3473: except for 'list_search' and 'list' (which have more granularity, see the other switch below),
// refuse to render if the user is not allowed to see the class.
if (! UserRights::IsActionAllowed($this->m_oSet->GetClass(), UR_ACTION_READ, $this->m_oSet) == UR_ALLOWED_YES) {
$sHtml .= $oPage->GetP(Dict::Format('UI:Error:ReadNotAllowedOn_Class', $this->m_oSet->GetClass()));
return $sHtml;
}
}
switch ($this->m_sStyle) {
case 'count':
if (isset($aExtraParams['group_by']))
{

View File

@@ -103,6 +103,10 @@ define('LINKSET_EDITMODE_ACTIONS', 2); // Show the usual 'Actions' popup menu
define('LINKSET_EDITMODE_INPLACE', 3); // The "linked" objects can be created/modified/deleted in place
define('LINKSET_EDITMODE_ADDREMOVE', 4); // The "linked" objects can be added/removed in place
interface iAttributeNoGroupBy
{
//no method, just a contract on implement
}
/**
* Attribute definition API, implemented in and many flavours (Int, String, Enum, etc.)
@@ -3761,7 +3765,7 @@ class AttributeFinalClass extends AttributeString
*
* @package iTopORM
*/
class AttributePassword extends AttributeString
class AttributePassword extends AttributeString implements iAttributeNoGroupBy
{
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
@@ -3837,7 +3841,7 @@ class AttributePassword extends AttributeString
*
* @package iTopORM
*/
class AttributeEncryptedString extends AttributeString
class AttributeEncryptedString extends AttributeString implements iAttributeNoGroupBy
{
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
@@ -9217,7 +9221,7 @@ class AttributeSubItem extends AttributeDefinition
/**
* One way encrypted (hashed) password
*/
class AttributeOneWayPassword extends AttributeDefinition
class AttributeOneWayPassword extends AttributeDefinition implements iAttributeNoGroupBy
{
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;

View File

@@ -1186,6 +1186,30 @@ abstract class DBSearch
}
}
}
if (is_array($aGroupByExpr))
{
foreach($aGroupByExpr as $sAlias => $oGroupByExp)
{
/** @var \Expression $oGroupByExp */
$aFields = $oGroupByExp->ListRequiredFields();
foreach($aFields as $sFieldAlias)
{
$aMatches = array();
if (preg_match('/^([^.]+)\\.([^.]+)$/', $sFieldAlias, $aMatches))
{
$sFieldClass = $this->GetClassName($aMatches[1]);
$oAttDef = MetaModel::GetAttributeDef($sFieldClass, $aMatches[2]);
if ( $oAttDef instanceof iAttributeNoGroupBy)
{
throw new Exception("Grouping on '$sFieldClass' fields is not supported.");
}
}
}
}
}
$oSQLQuery = $oSearch->GetSQLQueryStructure($aAttToLoad, $bGetCount, $aGroupByExpr, null, $aSelectExpr);
$oSQLQuery->SetSourceOQL($oSearch->ToOQL());

View File

@@ -457,6 +457,7 @@ Dict::Add('EN US', 'English', 'English', array(
'UI:Error:ObjectsAlreadyDeleted' => 'Error: objects have already been deleted!',
'UI:Error:BulkDeleteNotAllowedOn_Class' => 'You are not allowed to perform a bulk delete of objects of class %1$s',
'UI:Error:DeleteNotAllowedOn_Class' => 'You are not allowed to delete objects of class %1$s',
'UI:Error:ReadNotAllowedOn_Class' => 'You are not allowed to view objects of class %1$s',
'UI:Error:BulkModifyNotAllowedOn_Class' => 'You are not allowed to perform a bulk update of objects of class %1$s',
'UI:Error:ObjectAlreadyCloned' => 'Error: the object has already been cloned!',
'UI:Error:ObjectAlreadyCreated' => 'Error: the object has already been created!',

View File

@@ -439,7 +439,8 @@ Dict::Add('FR FR', 'French', 'Français', array(
'UI:Error:ObjectCannotBeUpdated' => 'Erreur: l\'objet ne peut pas être mis à jour.',
'UI:Error:ObjectsAlreadyDeleted' => 'Erreur: les objets ont déjà été supprimés !',
'UI:Error:BulkDeleteNotAllowedOn_Class' => 'Vous n\'êtes pas autorisé à faire une suppression massive sur les objets de type %1$s',
'UI:Error:DeleteNotAllowedOn_Class' => 'Vous n\'êtes pas autorisé supprimer des objets de type %1$s',
'UI:Error:DeleteNotAllowedOn_Class' => 'Vous n\'êtes pas autorisé à supprimer des objets de type %1$s',
'UI:Error:ReadNotAllowedOn_Class' => 'Vous n\'êtes pas autorisé à voir des objets de type %1$s',
'UI:Error:BulkModifyNotAllowedOn_Class' => 'Vous n\'êtes pas autorisé à faire une modification massive sur les objets de type %1$s',
'UI:Error:ObjectAlreadyCloned' => 'Erreur: l\'objet a déjà été dupliqué !',
'UI:Error:ObjectAlreadyCreated' => 'Erreur: l\'objet a déjà été créé !',