2

Salesforce is performing manual security review in our package. They have found SessionID access Vulnerability in one of our file where we are using Metadata API to grant permissions on profile and permission sets. They have mentioned following code block in the detail which has this issue :

public static MetadataService.MetadataPort createService() {
    MetadataService.MetadataPort service = new MetadataService.MetadataPort();
    service.SessionHeader = new MetadataService.SessionHeader_element();
    service.SessionHeader.sessionId = UserInfo.getSessionId();
    return service;
}

In the notes they have added this comment :

Please use OAuth, (try JWT flows and look into admin pre-authorization). Do not touch user credentials in a managed package.

They have not provided any link as why this is a vulnerability. So I am asking you guys if you can provide more insight on this.

  1. Why this is a vulnerability?
  2. This part of functionality is only accessible by Admin of the org in our case so can we simply put it in the False positive?
  3. Could you provide any detailed link which explains how we can fix this using OAuth etc (in more secure way.)?
1
  • I am not sure why is this a vulnerability, but here are few points: 1) If this code will be called from a lighting context , then session id will be of lightning context which sometimes may affect functionality. 2) You can have connected app created and use oauth 2.0 (JWT Bearer Flow ) for fetching oauth token. help.salesforce.com/… Jun 15 at 12:56
1

Use of API Sids has never been allowed in managed packages. These are allowed only in unpackaged code. The only issue is that there weren't automated tools in place to consistently enforce this. As these automated tools are rolled out, a lot of apps will start failing the review because of session Id theft and existing apps will start getting flagged.

To understand why grabbing a user's sid and then logging into another API as them is something we don't want managed packages to do, consider the following:

  1. Impersonation: The logs will then record those calls as being done by the user when they were done by your app. If you use OAuth, you are logging in with credentials associated to the app and the logs will correctly track what is going on.

  2. Lack of Authorization: If you are going to log in on behalf of a user to another service, then you should be authorized to do this rather than doing it without the user's consent. In Salesforce the admin can pre-authorize you and so grant consent on behalf of another user, but an app can't authorize itself. With OAuth, there is an authorization step so that you are not silently stealing credentials and taking actions without the user's approval.

  3. Lack of Scoping: We want to follow the principle of least privilege and scope down the allowed operations to be as close to what you need as possible. OAuth allows you to choose and even define scopes, whereas API Sids have no ability to do this.

  4. Namespace Escape: All code running in a managed package should be scoped to a namespace. Any attempts to break out of that namespace and run in a different scope are considered vulnerabilities in the security review. This includes attempts to grab the session id of the salesforce origin via a weblink as well as attempts to grab the API sid, which is not namespaced. If an admin uses your app, you could grab that admin's sid and then uninstall a package in a different namespace, or install an apex class in the unpackaged namespace. That is a clear escape from your own namespace.

Because of the above risks, API Enabled Sids are considered unsafe and there are both on going efforts to remove them from the product as well as automated and manual efforts to flag their usage in managed packages. Over time, these efforts will get more and more strict, so please avoid them now, and if your app is using them, please start refactoring your app to use OAuth instead.

This is basically a continuation of the home page component issue, which is another ongoing locking down of the platform to prevent use of credentials that don't belong to the managed package.

3
  • Thank you so much for such detailed explanation. I have a related question. As Salesforce has asked us to fix similar instances in the code there are some places in Visualforce pages where we are using Connection.js and it requires to use session id for this. Is this also vulnerable or it is fine?
    – Mr.Frodo
    Jun 17 at 16:40
  • Hi @Robert Just wanted to get your attention if you have any suggestion for my question in above comment.
    – Mr.Frodo
    Jun 22 at 15:04
  • @Mr.Frodo IIRC, Nothing wrong with connection.js, just use Oauth to get a token and pass that to the library instead of the API sid Jun 22 at 19:58
2

You can try steps mentioned in below link for the oOuth way. Link - https://www.gscloudsolutions.com/blogpost/Using-Named-Credentials-with-the-Apex-Wrapper-Salesforce-Metadata-API-apex-mdapi?blogpost=true

This uses connected app, named credentials and auth provider. And it modifies endpoint in MetadataPort class,

public class MetadataPort {
        // Update endpoint_x to the name of your Named Credential
        public String endpoint_x = 'callout:ApexMDAPI/services/Soap/m/38.0';

and use token like below -

    public static MetadataService.MetadataPort createService()
    {
        MetadataService.MetadataPort service = new MetadataService.MetadataPort();
        service.SessionHeader = new MetadataService.SessionHeader_element();
        // service.SessionHeader.sessionId = UserInfo.getSessionId();
        service.SessionHeader.sessionId = '{!$Credential.OAuthToken}';

        return service;
    }
1
  • 1
    Thanks for the doc's link. This is my last resort. I am checking if anyone has more information to share about other 2 questions.
    – Mr.Frodo
    Jun 15 at 14:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.