
Salesforce object access auditor
Publié en open source par NCC Group Plc - https://www.nccgroup.com/
Développé par Jerome Smith @exploresecurity (avec remerciements à Viktor Gazdag @wucpi)
https://www.github.com/nccgroup/raccoon
Publié sous licence AGPL - se référer au fichier LICENSE pour plus d'informations.
Cet outil détermine quels Profils et Ensembles d'autorisations (avec utilisateurs actifs) disposent d'une combinaison de permissions en lecture/édition/suppression sur TOUS les enregistrements d'un ensemble donné d'objets, sur la base de leurs paramètres de partage et d'objets effectifs. À partir de cette sortie, il est possible d'étudier les erreurs de configuration qui permettent potentiellement un accès excessif aux objets contenant des données sensibles. Reportez-vous à l'article de blog associé pour le contexte à https://research.nccgroup.com/2021/06/28/are-you-oversharing-in-salesforce.
Il est recommandé de vérifier manuellement les résultats en se référant directement à la configuration Salesforce et/ou en testant les Profils et Ensembles d'autorisations concernés. En cas de divergence, veuillez ouvrir un ticket avec le plus de détails possible.
Prérequis :
requests (couvert par requirements.txt)username + password + (facultatif) token SOIT sessionId (plus de détails dans la section Authentification).Créez un fichier de configuration JSON (ou utilisez config.json comme modèle) et remplissez-le selon vos besoins :
{
"hostname": "somewhere.my.salesforce.com",
"username": "",
"password": "",
"token": "<optional token>",
"sessionId": "",
"objects": ["Account", "Contact"],
"checkLimits": true,
"debug": <optional debug level (0, 1 or 2)>
}
objects est une liste d'objets Salesforce d'intérêt (c'est-à-dire les données qui vous importent le plus). L'utilisation des noms d'API officiels est la méthode la plus fiable, mais si aucune correspondance n'est trouvée, Raccoon tentera des correspondances simples basées, par exemple, sur le libellé d'affichage. Si Raccoon ne trouve toujours pas de correspondance, le programme continuera mais signalera ce problème dans sa sortie.
checkLimits vous permet de vérifier le quota d'appels API restants pour l'instance étudiée au cours de la période glissante de 24 heures. Raccoon effectue relativement peu d'appels par objet (en plus d'un nombre fixe par exécution) mais, par courtoisie, ce paramètre vous permet de vérifier vos limites avant de continuer. La valeur par défaut est true. Le nombre total de requêtes éventuellement restantes au point de contrôle n'est pas certain, car le nombre d'appels dépendra du nombre d'objets dotés d'un modèle de partage 'Controlled by Parent'. Le nombre indiqué suppose qu'ils en ont tous et constitue donc un maximum.
Exécutez :
git clone https://github.com/nccgroup/raccoon
pip3 install -r requirements.txt
python3 raccoon.py <config_file>
Lorsqu'un nom d'utilisateur et un mot de passe sont utilisés, notez qu'un jeton de sécurité peut également être requis (si la connexion provient d'une adresse IP hors des plages d'accès réseau définies). Reportez-vous à cet article pour plus d'informations.
L'alternative consistant à utiliser l'ID de session est utile dans de nombreux cas :
Pour obtenir l'ID de session :
sid : assurez-vous de prendre celui dont l'attribut Domain inclut my.salesforce.com ou cloudforce.comExemple de sortie (abrégée et anonymisée) :
Raccoon - Salesforce object access auditor
- version 1.0
- https://www.github.com/nccgroup/raccoon
* Refer to README for usage notes including important limitations *
Target instance: somewhere.my.salesforce.com
- Login successful
4,969,529 API requests can be sent to this instance from a 24-hour limit of 5,000,000
- Up to 33 further requests are required to complete (3 requests sent so far)
- Do you want to continue? Enter 'y' to proceed: y
Validating objects
- Found object 'Accounts' with API name 'Account'
- Found object 'Contact' with API name 'Contact'
- Found object 'Quotes' with API name 'Quote__c'
- Found object 'Quote Lines' with API name 'QuoteLine__c'
Evaluating 28 Profiles and 104 Permission Sets
- Profiles with active users: 15
- Permission Sets with active users: 67
- Ignoring 50 unused Profiles and Permission Sets
Global Sharing Overrides (ALL records for ALL objects)
------------------------------------------------------
READ/EDIT/DELETE [C]ustom Active/Total [G]uest[E]xt[I]nt
Profiles
- System Administrator 61/91 [I]
READ
Profiles
- Integration User [C] 1/1 [I]
- Analytics Cloud Integration User 1/1 [I]
Object Sharing (ALL records for EACH object)
--------------------------------------------
Account:
Organization-wide default sharing
- Internal: Public Read Only
- External: <Undefined>
READ/EDIT/DELETE [C]ustom Active/Total [G]uest[E]xt[I]nt
Profiles
- Integration User [C] 1/1 [I]
Permission Sets (* Groups)
- Mulesoft Integration [C] 2/2 [I]
READ
Profiles
- Read Only [C] 192/199 [I]
- Sales User [C] 192/248 [I]
- Finance User [C] 16/20 [I]
- Standard User 6/3075 [I]
Permission Sets (* Groups)
* Accounts PS Group [C] 36/39 [I]
- Sales Operations [C] 24/26 [I]
- SharePoint User [C] 3/4 [I]
Sharing Rules (manual check required):
- Criteria-based rules configured
- Ownership-based rules configured
Contact:
Organization-wide default sharing
- Internal: Controlled by Parent
- External: <Undefined>
Parent object: 'Account'
- Internal: Public Read Only
- External: <Undefined>
READ/EDIT/DELETE [C]ustom Active/Total [G]uest[E]xt[I]nt
Profiles
- Integration User 1/1 [I]
Permission Sets (* Groups)
- Mulesoft Integration [C] 2/2 [I]
READ
Profiles
- Read Only [C] 192/199 [I]
- Sales User [C] 192/248 [I]
- Finance User [C] 16/20 [I]
- Standard User 6/3075 [I]
Permission Sets (* Groups)
- Sales Operations [C] 24/26 [I]
Quote__c:
Organization-wide default sharing
- Internal: Public Read/Write
- External: <Undefined>
READ/EDIT [C]ustom Active/Total [G]uest[E]xt[I]nt
Profiles
- Sales User [C] 192/248 [I]
READ
Profiles
- Finance User [C] 16/20 [I]
Permission Sets (* Groups)
- Mulesoft Integration [C] 2/2 [I]
QuoteLine__c:
Organization-wide default sharing
- Internal: Controlled by Parent
- External: <Undefined>
Parent object: 'Quote__c'
- Internal: Public Read/Write
- External: <Undefined>
READ/EDIT/DELETE [C]ustom Active/Total [G]uest[E]xt[I]nt
Profiles
- Sales User [C] 192/248 [I]
READ
Profiles
- Finance User [C] 16/20 [I]
Permission Sets (* Groups)
- Mulesoft Integration [C] 2/2 [I]
Total API requests sent: 31
Raccoon n'examine que les Profils et Ensembles d'autorisations ayant des utilisateurs actifs afin de réduire la verbosité de sa sortie. Ces informations sont affichées, après quoi :
Si l'attribution des privilèges a été effectuée via un Groupe d'ensembles d'autorisations (Permission Set Group), et non via un seul Ensemble d'autorisations, un astérisque apparaît comme marqueur d'indentation à gauche du nom, à la place du trait d'union habituel (Accounts PS Group dans l'exemple de sortie ci-dessus). De plus, le fait que le Profil ou l'Ensemble d'autorisations soit personnalisé est également indiqué (pour les Ensembles d'autorisations, personnalisé signifie « créé par un administrateur », sinon il « est standard et lié à une licence d'ensemble d'autorisations spécifique » [ref]).
Pour le partage global et le partage par objet, les Profils et Ensembles d'autorisations sont ordonnés en fonction de l'intérêt probable. Le premier niveau de tri concerne le type d'utilisateur assigné : « guest » (non authentifié) en premier, puis « external » (divers types d'utilisateurs de portail), puis « internal » (tout le reste). Il est important de noter que « external » ici se rapporte à la définition utilisée dans le contexte du « modèle de partage externe » (external sharing model) [ref]. L'idée est de mettre en évidence un partage potentiellement excessif pour les utilisateurs non authentifiés ou de portail. Cela reste toutefois quelque peu expérimental, car la documentation Salesforce n'est pas exhaustive dans sa liste de valeurs « UserType » valides pour l'objet « User » [ref]. Par conséquent, une mauvaise classification est possible - veuillez ouvrir un ticket dans un tel cas. Le second niveau de tri est basé sur le nombre d'utilisateurs actifs : les plus élevés d'abord (le nombre total d'utilisateurs assignés est également affiché à titre d'information).
L'objectif principal de Raccoon est de mettre en évidence les cas d'accès généralisé à tous les enregistrements, et il couvre :
Les facteurs suivants, qui n'affectent qu'un sous-ensemble d'enregistrements, ne sont pas évalués :
Certains objets, tels que « User » et « File », ne correspondent pas au modèle de partage standard et/ou d'autres permissions système entrent en jeu. Les cas connus sont signalés dans la sortie s'ils sont spécifiés dans la liste objects.
Les instances comptant plus de 2 000 Profils et Ensembles d'autorisations combinés ne sont pas prises en charge en raison des limites de la plateforme sur l'utilisation de « GROUP BY » dans les instructions SOQL. Cette marge est généreuse et ne devrait constituer un obstacle que dans les cas les plus extrêmes.
Cet outil n'effectue que des opérations de lecture. Il peut donc être surprenant de voir « Modify Metadata Through Metadata API Functions » comme exigence pour le compte utilisé pour exécuter l'outil. Cependant, au moment de la rédaction, il ne semble pas possible de configurer un compte avec des permissions en lecture seule pour l'API Metadata. D'après la documentation :
Identifiez un utilisateur disposant de la permission API Enabled et de la permission Modify Metadata Through Metadata API Functions ou de la permission Modify All Data. Ces permissions sont requises pour accéder aux appels de l'API Metadata. Si un utilisateur a besoin d'accéder aux métadonnées mais pas aux données, activez la permission Modify Metadata Through Metadata API Functions. Sinon, activez la permission Modify All Data.
Il est donc suggéré d'utiliser « Modify Metadata Through Metadata API Functions » plutôt que « Modify All Data ».
Si le problème concerne la connexion, veuillez d'abord revérifier le nom d'hôte, le nom d'utilisateur, le mot de passe et le jeton de sécurité (si requis). Pensez également à vérifier si le mot de passe doit être réinitialisé (essayez la connexion web Salesforce habituelle), car cette situation renvoie une erreur impossible à distinguer d'un identifiant invalide. Si vous utilisez un ID de session, assurez-vous qu'il est valide pour le bon domaine.
Exécutez l'outil avec debug défini sur 2, car la sortie verbeuse peut aider à identifier la cause. Ce niveau génère également une trace de pile (stack trace) dans un fichier dont le nom est indiqué dans la sortie. Si vous signalez un problème, veuillez inclure à la fois la sortie console et la trace de pile (anonymisez si nécessaire).
Connu pour fouiller dans les objets.