-
Notifications
You must be signed in to change notification settings - Fork 3
CRUD Probing
CRUD probing empirically tests what DML operations the current session can perform on each Salesforce object. Instead of relying on metadata alone, it attempts actual Create, Read, Edit, and Delete operations to determine effective permissions.
- For each target object, ForceHound calls
getObjectInfoto discover field metadata (required fields, data types, reference targets, picklist values) -
Create probe: Builds a minimal valid record using
dummy_values.pyvalue generation, submits viacreateRecord. If it succeeds, the record is immediately deleted to clean up. -
Read probe: Fetches one existing record via
getRecordWithFields. - Edit probe (aggressive mode only): Saves the current value of a field, writes a new value, then restores the original.
- Delete probe (aggressive mode only): Deletes one existing record per object. This is destructive.
Results are emitted as CrudCanCreate, CrudCanRead, CrudCanEdit, CrudCanDelete edges from the session user to each SF_Object.
# Basic CRUD probe (create + read only)
forcehound --collector aura ... --crud -o output.json
# Aggressive mode (create + read + edit + delete)
forcehound --collector aura ... --crud --aggressive -o output.json
# Limit to specific objects
forcehound --collector aura ... --crud --crud-objects Account,Contact,Opportunity
# Dry run — log what would be probed without executing
forcehound --collector aura ... --crud --crud-dry-run
# Allow delete-probing protected objects (User, Profile, etc.)
forcehound --collector aura ... --crud --aggressive --unsafe| Edge | Meaning |
|---|---|
CrudCanCreate |
Session user can create records of this object type |
CrudCanRead |
Session user can read records of this object type |
CrudCanEdit |
Session user can edit records of this object type |
CrudCanDelete |
Session user can delete records of this object type |
These are distinct from the API collector's CanCreate/CanRead/CanEdit/CanDelete edges, which represent metadata-declared ObjectPermissions on PermissionSets.
Certain objects are always skipped to avoid disrupting org configuration:
- System objects: Organization, SetupAuditTrail, LoginHistory, ApexLog, AsyncApexJob, CronTrigger, CronJobDetail
- Identity objects: Profile, PermissionSet, PermissionSetAssignment, PermissionSetGroup, PermissionSetGroupComponent, UserRole, GroupMember
- Objects ending in:
__ChangeEvent,__Share,__Feed,__History
Even in aggressive mode, the following objects are protected from deletion unless --unsafe is used:
User, Profile, PermissionSet, UserRole, Group, Organization, plus auth/integration objects (OAuthToken, ConnectedApplication, ExternalDataSource, NamedCredential), Apex code objects, Aura/LWC bundles, Visualforce objects, Flows, and audit/logging objects.
Edit forcehound/collectors/crud/dummy_values.py to customize the values used for create/edit probes. The module generates type-appropriate dummy values (strings, numbers, dates, emails, URLs, picklist selections, reference lookups) based on field metadata.
In aggressive mode, deletions are logged to forcehound_deletions_<timestamp>.json with the record ID, object name, and field snapshot of each deleted record.