<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=490755098261949&amp;ev=PageView&amp;noscript=1">

NEW CASE STUDY: See how we built a custom digital platform for Melissa Wood Health

Bug or Feature? Uncovering a Potential Salesforce API Security Breach

Pavel Savinov
Author Pavel Savinov
Published On Feb 27, 2023
Cover (1)-1 Frame 887-1

According to a 2022 report by IBM, a data breach costs an organization more than $4 million on average, and 19% of breaches occurred because of a compromise at a business partner. It’s clear that keeping data safe has never been more crucial to a company’s bottom line, yet even high-profile technology companies sometimes fall short when it comes to their security practices.

A long-term project we’re working on here at Heady involves the use of Salesforce OCAPI (Open Commerce API). OCAPI is a collection of highly customizable APIs that support ecommerce-related applications, providing similar functionality as a Salesforce storefront but through API.

One of OCAPI’s most interesting and useful functionalities is called "Order On Behalf.” This function allows a specific user (the so-called "agent user") with specific roles to get a token that enables them to manipulate other users’ data and place orders on their behalf. Use cases for this include a customer service representative being able to finish the checkout process on a customer’s behalf if they’re having technical difficulties, or if the customer wants to add additional items to their order. The process of agent token request is fairly easy; it’s simply a matter of the appropriate configuration and following the steps described in the corresponding documentation section.

Once the application (for example, a customer service application) gets the agent token, it’s not possible to use it directly to access a particular user's data. The agent has to authenticate as a target user first, and there’s a specific API to do that as well. As mentioned in the API specification, the API "obtains a new agent on behalf of token for a registered customer.” They also provide a token structure, mentioning 3 parts of it: header, payload, and signature.

Cover (2)-2
Frame 888

{
    "_v": "1",

    "exp": 1663230568,

    "iat": 1663228768,

    "iss": "our-salesforce-instance-client-id",
    
    "sub": "{\"_v\":\"1\",\"agent\":\"agent@acme.com\",\"agent_id\":\"abcdefg\",\"customer_info\":    {\"customer_id\":\"0123456789\",\"guest\":false,\"visit_id\":\"9876543210\"}}"

 A look at the Salesforce API code that provides the agent token.

According to a 2022 report by IBM, a data breach costs an organization more than $4 million on average, and 19% of breaches occurred because of a compromise at a business partner. It’s clear that keeping data safe has never been more crucial to a company’s bottom line, yet even high-profile technology companies sometimes fall short when it comes to their security practices.

A long-term project we’re working on here at Heady involves the use of Salesforce OCAPI (Open Commerce API). OCAPI is a collection of highly customizable APIs that support ecommerce-related applications, providing similar functionality as a Salesforce storefront but through API.

One of OCAPI’s most interesting and useful functionalities is called "Order On Behalf.” This function allows a specific user (the so-called "agent user") with specific roles to get a token that enables them to manipulate other users’ data and place orders on their behalf. Use cases for this include a customer service representative being able to finish the checkout process on a customer’s behalf if they’re having technical difficulties, or if the customer wants to add additional items to their order. The process of agent token request is fairly easy; it’s simply a matter of the appropriate configuration and following the steps described in the corresponding documentation section.

Once the application (for example, a customer service application) gets the agent token, it’s not possible to use it directly to access a particular user's data. The agent has to authenticate as a target user first, and there’s a specific API to do that as well. As mentioned in the API specification, the API "obtains a new agent on behalf of token for a registered customer.” They also provide a token structure, mentioning 3 parts of it: header, payload, and signature.

As you can see, it includes a specific customer ID we’re authenticated for. Furthermore, the signature guarantees the integrity of the token, so there’s no way to decode the payload, change the customer ID, encode that same payload, and use it for another customer.

The problem is that the user who possesses this token can now access any other user's resources. For example, if the agent authenticates as Customer A, they also have the ability to access Customer B resources including personally identifiable information (PII) such as their name, email address, home address, order history, and even their credit or debit card number.

While the token used for these manipulations is specific to Customer A, Salesforce doesn't check customer ID in any of the resource requests, meaning that possessing Token A (signed for Customer A) gives a user the power to access any customer’s data. Thankfully, it only works this way for the agent token that’s given to a business manager when they authenticate on behalf of a customer, and not for the normal user token. But if a signed customer token falls into the hands of a bad actor, they can use it to obtain any customer’s PII. Think of it like stealing one person’s bag and gaining a master key that unlocks any house in their neighborhood.

While Salesforce says this function is working as intended, from this end it looks like a security issue that creates a potential data breach risk — and considering how many companies use Salesforce, the consequences could be significant. With expensive data breaches on the rise, it’s crucial that organizations pay close attention to the design and implementation of their API and perform penetration testing for any feature that interacts with PII to ensure sensitive data stays private.

What do you think: bug or feature?

Pavel Savinov is a software engineer at Heady.

According to a 2022 report by IBM, a data breach costs an organization more than $4 million on average, and 19% of breaches occurred because of a compromise at a business partner. It’s clear that keeping data safe has never been more crucial to a company’s bottom line, yet even high-profile technology companies sometimes fall short when it comes to their security practices.

A long-term project we’re working on here at Heady involves the use of Salesforce OCAPI (Open Commerce API). OCAPI is a collection of highly customizable APIs that support ecommerce-related applications, providing similar functionality as a Salesforce storefront but through API.

One of OCAPI’s most interesting and useful functionalities is called "Order On Behalf.” This function allows a specific user (the so-called "agent user") with specific roles to get a token that enables them to manipulate other users’ data and place orders on their behalf. Use cases for this include a customer service representative being able to finish the checkout process on a customer’s behalf if they’re having technical difficulties, or if the customer wants to add additional items to their order. The process of agent token request is fairly easy; it’s simply a matter of the appropriate configuration and following the steps described in the corresponding documentation section.

Once the application (for example, a customer service application) gets the agent token, it’s not possible to use it directly to access a particular user's data. The agent has to authenticate as a target user first, and there’s a specific API to do that as well. As mentioned in the API specification, the API "obtains a new agent on behalf of token for a registered customer.” They also provide a token structure, mentioning 3 parts of it: header, payload, and signature.

LET'S TALK IT OUT.

Figuring out your next step? We're here for you.

Or drop us a line.

hello@heady.io