
Salesforce object access auditor
NCC Group Plc によりオープンソースとして公開 - https://www.nccgroup.com/
開発: Jerome Smith @exploresecurity(協力: Viktor Gazdag @wucpi)
https://www.github.com/nccgroup/raccoon
AGPL のもとで公開 - 詳細は LICENSE を参照。
このツールは、指定されたオブジェクト群のすべてのレコードに対して、読み取り/編集/削除権限の何らかの組み合わせを持つプロファイルと権限セット(アクティブなユーザーがいるもの)を、その実効共有設定とオブジェクト設定に基づいて特定します。この出力から、機密データを保持するオブジェクトへの過剰なアクセスを許す可能性のある設定ミスを調査できます。背景については、付随するブログ記事 https://research.nccgroup.com/2021/06/28/are-you-oversharing-in-salesforce を参照してください。
結果は、Salesforce の設定を直接参照して手動で検証し、影響を受けるプロファイルおよび権限セットをテストすることをお勧めします。不一致が見つかった場合は、できるだけ詳しい情報を添えて issue を報告 してください。
要件:
requests モジュール(requirements.txt に含まれています)username + password +(任意の)token または sessionId のいずれかを指定します(詳細は 認証 セクションを参照)。JSON 設定ファイルを作成し(または config.json をテンプレートとして使用し)、必要に応じて入力します:
{
"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 は、対象とする Salesforce オブジェクト(つまり、最も重視するデータ)のリストです。正式な API 名を使用するのが最も確実な方法ですが、一致するものが見つからない場合、Raccoon は表示ラベルなどに基づいていくつかの単純な一致を試みます。それでも一致するものが見つからない場合、プログラムは続行されますが、出力でその旨が示されます。
checkLimits を使用すると、調査対象のインスタンスについて、24 時間のローリング期間内の API 呼び出しの残り許容量を確認できます。Raccoon はオブジェクトごとに比較的少数の呼び出しを行います(実行ごとの固定数に加えて)が、念のため、このパラメータを使用して事前に制限を確認できます。デフォルト値は true です。チェックポイントでの残りリクエスト数の合計は確定的ではありません。呼び出し数は、'Controlled by Parent' 共有モデルを持つオブジェクトの数に依存するためです。記載されている数値は、それらすべてが該当すると仮定した場合の最大値です。
実行:
git clone https://github.com/nccgroup/raccoon
pip3 install -r requirements.txt
python3 raccoon.py <config_file>
ユーザー名とパスワードを使用する場合、セキュリティトークンも必要な場合があることに注意してください(定義されたネットワークアクセス範囲外の IP アドレスから接続する場合)。詳細については、この記事 を参照してください。
セッション ID を使用する代替方法は多くの場合に役立ちます:
セッション ID を取得するには:
sid Cookie が複数ある場合があります。Domain 属性に my.salesforce.com または cloudforce.com が含まれているものを必ず取得してくださいサンプル出力(要約・匿名化済み):
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 は、出力の冗長性を減らすために、アクティブなユーザーがいるプロファイルと権限セットのみを調査します。これに関する情報が表示され、その後に以下が行われます:
特権の割り当てが単一の権限セットではなく権限セットグループを通じて行われた場合、名前の左側には通常のハイフンの代わりにアスタリスクがインデントマーカーとして表示されます(上記のサンプル出力の Accounts PS Group)。さらに、プロファイルまたは権限セットがカスタムであるかどうかも表示されます(権限セットの場合、カスタムは「管理者によって作成された」ことを意味し、それ以外は「標準であり、特定の権限セットライセンスに関連する」ことを意味します [ref])。
グローバル共有とオブジェクト共有の両方において、プロファイルと権限セットは、関心の高さを反映するように並べられます。最初の並べ替えレベルは、割り当てられたユーザーのタイプです。'guest'(未認証)が最初、次に 'external'(さまざまなタイプのポータルユーザー)、その後に 'internal'(その他すべて)が続きます。ここで 'external' は「外部共有モデル」の文脈で使用される定義に関連していることに注意してください [ref]。この意図は、未認証ユーザーまたはポータルユーザーに対する過剰な共有の可能性を強調することです。ただし、Salesforce のドキュメントでは 'User' オブジェクトの有効な 'UserType' 値のリストが網羅的ではないため、この機能はやや実験的です [ref]。その結果、誤分類が発生する可能性があります。その場合は、issue を報告 してください。2 番目の並べ替えレベルは、アクティブなユーザー数に基づいています(多い順。割り当てられたユーザーの合計数も参考情報として表示されます)。
Raccoon の主な目的は、すべてのレコードへの広範なアクセスが見られるインスタンスを強調することであり、以下を対象としています:
レコードのサブセットにのみ影響する以下の要因は評価されません:
'User' や 'File' などの一部のオブジェクトは、標準の共有モデルに適合しない、または他のシステム権限が関与します。既知のインスタンスは、objects リストで指定されている場合、出力でフラグ付けされます。
プロファイルと権限セットの合計が 2,000 を超えるインスタンスは、SOQL ステートメントでの 'GROUP BY' の使用に関するプラットフォームの制限によりサポートされていません。これは非常に余裕のある許容値であり、ごく極端な場合にのみ制約となるはずです。
このツールは読み取り操作のみを実行します。そのため、ツールの実行に使用するアカウントの要件として「'Modify Metadata Through Metadata API Functions'」が挙げられているのは意外に思えるかもしれません。ただし、本稿執筆時点では、Metadata API への読み取り専用権限を持つアカウントを構成することはできないようです。ドキュメント には次のように記載されています:
API Enabled 権限と、Modify Metadata Through Metadata API Functions 権限または Modify All Data 権限を持つユーザーを特定します。これらの権限は Metadata API 呼び出しへのアクセスに必要です。ユーザーがデータではなくメタデータへのアクセスを必要とする場合は、Modify Metadata Through Metadata API Functions 権限を有効にします。それ以外の場合は、Modify All Data 権限を有効にします。
したがって、'Modify All Data' ではなく 'Modify Metadata Through Metadata API Functions' を使用することをお勧めします。
ログインに関する問題の場合は、まずホスト名、ユーザー名、パスワード、セキュリティトークン(必要な場合)を再確認してください。また、パスワードのリセットが必要かどうかも検討してください(通常の Salesforce Web ログインを試してください)。この状態は無効なログインと区別できないエラーを返すためです。セッション ID を使用している場合は、正しいドメインに対して有効であることを確認してください。
原因の特定に役立つ詳細な出力が得られるため、debug を 2 に設定してツールを実行してください。このレベルでは、スタックトレースも出力内で指定されたファイルに出力されます。問題を報告する場合は、コンソール出力とスタックトレースの両方を含めてください(必要に応じて匿名化してください)。
オブジェクトを漁ることで知られているからです。