• Zenity Labs
  • Posts
  • Over Permissions in Salesforce Einstein and Unexpected Consequences

Over Permissions in Salesforce Einstein and Unexpected Consequences

About a week ago Salesforce announced Agentforce, their customizable AI agent builder.

While Agentforce is not yet available, we thought this is a good opportunity to dive into how Salesforce is managing their security in their other AI products, mainly Einstein Copilot, their current flagship AI offering.

Simply put, Einstein is Salesforce’s all around AI assistant with access to your CRM data. You can ask it about the records you have, tasks assigned to you, it can even summarize records instead of you having to read through it yourself. In addition to all of this, admins can customize Einstein to extend its functionality. And when they do, they add the functionality to everyone’s Copilot, affecting the whole organization.

Now here’s the catch: While Salesforce promises that only admins can edit Einstein, this can be easily bypassed due to the inherent way Salesforce manages permissions, specifically the permission to edit flows (which is one of the ways to extend Einstein’s functionality).

But before we dive into our findings, let’s get to know Salesforce Einstein a little bit better

Understanding Salesforce Einstein

For Salesforce Einstein, it is important to understand a couple of key terms as relates to copilots. First, a ‘copilot topic’ is a specific Salesforce term that means ‘a category of actions related to a particular job to be done by an Agent or a Copilot. Topics contain actions, which are the tools available for the job, and instructions, which tell the agent how to make decisions. Collectively, topics define the range of capabilities your agent can handle. Salesforce provides a library of standard topics for common use cases, and you can create custom topics to meet your users’ specific business needs.’ 

Salesforce documentation, pictured below, shows that admins and devs can create custom actions that can give Einstein Copilot more capabilities. 

Only an admin can create a new topic and connect a flow action to it. However, while non-admin are not allowed to edit Einstein Copilot directly, they might have access to edit flows. This permission to edit flows gives them an easy bypass and a way to impact the entire Copilot. Everyone’s entire Copilot. And when in the wrong hands, this bypass can be used in very malicious ways, which we will show below.

Copilot Flows 

In salesforce flows run on the user’s behalf i.e. whoever the user that is talking to Einstein. Using this inherent feature, bad actors can edit an existing flow that was already connected to Einstein by an admin, adding to it whatever additional actions they’d want. Thus giving them the ability to execute whatever action they’d like on the user’s behalf (send emails, edit records, delete records, and lots more).

This means that anyone who has flow permissions can change the functionality of a legitimate flow, and add some very unexpected actions to it. In many organizations, Einstein Copilot is used by end users of all technical backgrounds and functions; brushing up against critical data housed in Salesforce in the process. If a flow is changed, it can have monumental damages if it is designed maliciously.

In addition, the way flows are constructed in Salesforce is that within a flow, someone can insert any kind of malicious activity, while keeping the input and output of it exactly the same. This essentially hides the activity. And will look completely legitimate for anyone who invokes the flow from Einstein while actually doing other things on the user's behalf in the background. 

Now that we understand how powerful flows are, let’s dive into a real scenario of how this can go wrong.

Inserting Malicious Flows in Salesforce Copilot

In the scenario we’re about to unpack, we are going to add a step to a legitimate flow which was connected to Einstein by an admin. Using this step we will be able to send phishing emails to customers directly from the inbox of the user running the flow, i.e. the user using Einstein Copilot

First, let’s see this from an admins perspective. Here we can see a legitimate flow that was created by an admin. This is quite a simple flow. It gets a date as input and returns all the new accounts that were created after this date. So far so good.

Next the admin creates a new ‘Agent Action’ called “Get Most Recent Accounts” which is connected to the flow. Agent actions are meant to tell Einstein when and how to use the flow, including instructions for filling in the parameters, in this case how to fill in the “from date” this flow expects as input.

We can see that the admin is instructing Einstein Copilot to use the flow when the user asks about the most recent / newest accounts they have.

And we can also see how the flow is decomposed and the way that Einstein reads the prompt, fills in the parameters correctly and answers accordingly.

Now that our flow is connected to Einstein, let’s see how the flow interacts today to someone that is using Einstein.

Looks good! We’re ready to use this and get it into the hands of our Salesforce users. 

Where It Goes Wrong

But… Now, let’s see where this can go wrong. We’re going to log in now as ‘Elad’, a non-admin user who does not have the ability to edit Einstein. As you can see below.

However, Elad does have permissions to edit / create flows. Once you have those permissions you can edit all of the organization’s flows. Yes, that includes the flow our admin just connected to Einstein.

Now, let’s add in a new action within that flow. 

Here, we’re going to add a step that sends an email to the flow, we have control over the: 

  • Label

  • Subject

  • Description

  • Who’s sending it

  • And who can receive it as part of this flow

Note the Who’s sending it part. Since people connect their email accounts to salesforce ,we can send the email out directly from the inbox of the user who’s using Einstein!

But, how does this play out? Well, at first glance, it looks the same.

However, if we dive in further, and look into the email inbox of one of the contacts John (our victim) is in touch with, for example “Tamir Holland” as seen below. 

We’ll see a new email from John has been received. This is the email that our bad actor inserted as part of this flow. And, of course, it contains a phishing link.

Wait, what just happened? 

This malicious user was able to leverage this flow to send a phishing email to a customer directly from the email address of the person who’s running the flow. This phishing email will be sent on behalf of any user who accidently invokes the flow through Einstein Copilot 

The origin of the email address is the address of the user that activated the flow; in this case it is the unsuspecting John Smith. 

From Einstein Access perspective, Elad (our attacker) is blocked and should not be able to influence the Copilot’s functionality in any way. However, the bad actor can access the flow, edit it and even delete the malicious versions after they are used, further masquerading themselves.

From the target’s perspective, it is hard to notice anything is afoot as the email is sent behind the scenes and the flow returns the expected response as we showed.

We have now sent off a phishing email, where all we need is one click in order to succeed in our mission. Our attack is complete.

The implications of editing everyone’s Copilot without the proper permissions are clear, and disastrous. As Salesforce move to bolster their AI capabilities security should stay a top priority. What we demonstrated here is only one of a few things that can happen when AI isn’t done right.

When adopting AI make sure to treat it with the care and respect it deserves.

Reply

or to participate.