Skip to main content
 
 
 
Splunk Lantern

Spike in exported records from Salesforce cloud

 

A sudden, high-volume increase in exported records can indicate unauthorized, non-compliant, and potentially malicious behavior. Because so many people in your organization have access to Salesforce, this is an activity you want to monitor for regularly.

Required data

Salesforce data

Procedure

  1. Populate the lookup_sfdc_usernames lookup provided by the Salesforce Add-on with live values from your site.
  2. Run the following search. You can optimize it by specifying an index and adjusting the time range.
|search ROWS_PROCESSED>0 EVENT_TYPE=API OR EVENT_TYPE=BulkAPI OR EVENT_TYPE=RestAPI
|lookup lookup_sfdc_usernames USER_ID
|bucket _time span=1d 
|stats sum(ROWS_PROCESSED) AS rows BY _time Username
|eventstats max(_time) as maxtime 
|stats count AS num_data_samples max(eval(if(_time >= relative_time(maxtime, "-1d@d"), 'rows',null))) AS rows avg(eval(if(_time<relative_time(maxtime,"-1d@d"),'rows',null))) AS avg stdev(eval(if(_time<relative_time(maxtime,"-1d@d"),'rows',null))) AS stdev BY Username
|eval lowerBound=(avg-stdev*2), upperBound=(avg+stdev*2)
|eval isOutlier=if(('rows' < lowerBound OR 'rows' > upperBound) AND num_data_samples >=7, 1, 0)

Search explanation

The table provides an explanation of what each part of this search achieves. You can adjust this query based on the specifics of your environment.

Splunk Search Explanation

|search ROWS_PROCESSED>0 

Filter for event types with at least one processed row. 

EVENT_TYPE=API OR EVENT_TYPE=BulkAPI OR EVENT_TYPE=RestAPI

Filter for API-related events.

|lookup lookup_sfdc_usernames USER_ID 

Convert the SFDC USER_ID into a friendly username via a lookup. 

|bucket _time span=1d 

Group events based on _time, effectively flattening the actual _time value to the same day.

|stats sum(ROWS_PROCESSED) AS rows BY _time USER_NAME

Count and aggregate per user, per day. 

|eventstats max(_time) as maxtime
|stats count AS num_data_samples max(eval(if(_time >= relative_time(maxtime, "-1d@d"), 'rows',null))) AS rows avg(eval(if(_time<relative_time(maxtime,"-1d@d"),'rows',null))) AS avg stdev(eval(if(_time<relative_time(maxtime,"-1d@d"),'rows',null))) AS stdev BY USER_NAME

Calculate the mean, standard deviation, and most recent value. 

|eval lowerBound=(avg-stdev*2), upperBound=(avg+stdev*2)

Calculate the bounds as a multiple of the standard deviation.

|eval isOutlier=if(('rows' < lowerBound OR 'rows' > upperBound) AND num_data_samples >=7, 1, 0)

Display events that have a frequency of occurrence above the calculated upperBound and seven or more data samples.

Next steps

While there are no traditional false positives in this search, there will be a lot of noise. Every time this search runs, it will accurately measure a spike in the number of records monitored. 

How you handle these alerts depends on where you set the standard deviation. If you set a low standard deviation (2 or 3), you are likely to get a lot of events that are useful only for contextual information. If you set a high standard deviation (6 or 10), the amount of noise can be reduced enough to send an alert directly to analysts.

For most environments, these searches can be run once a day, often overnight, without a lag. If you want to run this search more frequently, or if this search is too slow for your environment, use a summary index that first aggregates the data. 

When this search returns values, initiate your incident response process and identify the user demonstrating this behavior. Capture the time of the event, the user's role, and number of records downloaded. If possible, determine the system used to download this data and its location. Contact the user and their manager to determine if the download is authorized, and then document that it was authorized and by whom. If you cannot find authorization, the user credentials may have been used by another party and additional investigation is warranted.

GDPR Relevance: Detecting and proving that individuals within the organization are not abusing or misusing legitimate access to assets that store and process personal data is an industry best practice and can be considered an effective security control, as required by Article 32. This is applicable to processing personal data from the controller and needs to also be addressed if contractors or sub-processors from third countries or international organizations access and transfer personal data (Article 15).

Finally, you might be interested in other processes associated with the Protecting a Salesforce cloud deployment use case.