3

Let's face it. Salesforce Communities is expensive and not for everyone out there. I have a customer who wants to create a customer-facing site where non-logged in users can register themselves and later modify change their registrations.

I thought of using a Salesforce Site for it and not have users have user names and password. I just want them to use URLs to go back and edit their existing registration.

Multiple questions arise:

  1. Will Security Review "kill me" for not having proper authentification
  2. What are ways / are there ways to do this with user-specific, non-guessable URLs that are send via email?
  3. Some URL currently contain Salesforce Ids. Users could tamper them and call other valid Ids. Is there anything I can do against it?

I'm looking for pragmatic answers beyond "Insecure always use OAuth and Communities".

  • 1
    Encrypt the Salesforce ID using a private key and store the private key in your SF configs. This way anyone wont be able to guess next id. – Pranay Jaiswal Apr 29 at 15:28
2

One other thing to add re Encryption - in my experience, you need to store that key in a protected setting, and you need to generate that key on package install/update - it can't be hardcoded into the code in any way.

The use case here is to pre-populate a form on a force.com site using Contact data in SF. In the example above, we pass in the cid parameter as part of URL, which is an encrypted version of the Id and the value is stored in a custom field that is part of the package, so that customers can sync it to Marketing Cloud etc. We generate the encrypted version via a batch job that is updating the Contact records with other data.

The encryption/decryption is just using standard SF functionality e.g.

static String getEncryptedLink(String sLink) {
        Blob cipherText = Crypto.encryptWithManagedIV('AES256', getKey(), 
        Blob.valueOf(sLink));
        String encodedCipherText = EncodingUtil.convertToHex(cipherText); 
        return EncodingUtil.urlEncode(encodedCipherText,'UTF-8') ;
    }
}

static String getPlainLink(String sEncryptedLink) {
        String sCleanLink = EncodingUtil.urlDecode(sEncryptedLink,'UTF-8');
        Blob encodedEncryptedBlob = EncodingUtil.convertFromHex(sCleanLink);
        Blob decryptedBlob = Crypto.decryptWithManagedIV('AES256', getKey(), 
        encodedEncryptedBlob);
        String decryptedClearText = decryptedBlob.toString();
        return decryptedClearText;
}

The key itself is stored in a Protected Custom Setting (so not visible in customer org, and only visible to ISV if they grant login access) and we generate the key via the package install script - e.g. use something that we know will be 32 chars long, and random Org Id + Random Integer

So when someone loads the page, we can decrypt the id, query for Contact and display the data. If the submit the form, we can capture the Contact Id and link to the data they are submitting, send emails etc. Obviously, it doesn't have to be the actual Id, but we are supporting multiple objects, so it is helpful to have an Id we can then use to get underlying object type etc.

  • Sounds like you have implemented similar solutions. Would you mind describing the architecture and how you ensured security. – Robert Sösemann Apr 29 at 16:08
4

Will Security Review "kill me" for not having proper authentification

Most likely. Aside from breaking the MSA or Sites TOU, improper authentication is a big no-no. I'm not even sure how I'd describe this to the security team, because they will ask questions, and evasiveness is not a great way to get your app on the AppExchange. But to be certain, I'd ask someone there what is/is not permitted.

What are ways / are there ways to do this with user-specific, non-guessable URLs that are send via email?

Encryption. Have a randomly generated key stored in the org, use that to encrypt every URL parameter, decipher on load.

Some URL currently contain Salesforce Ids. Users could tamper them and call other valid Ids. Is there anything I can do against it?

Encryption. Visitors would never be able to find another valid value that wasn't given to them upfront, because they would be non-sequential and completely "random" from their perspective.

  • How would you suggest to change the solution to be safe enough and still not go the route of full auth or communities? – Robert Sösemann Apr 29 at 15:57
  • 2
    @RobertSösemann You can't "fake" authentication according to the various agreements. The only way to do it is to get real licenses. I don't know what the license options are these days or how they'd compare, but you really should be having a talk with an account executive. I believe there's a (relatively) inexpensive Sites.com license type instead of Communities. – sfdcfox Apr 29 at 16:18
  • 1
    You could generate a sufficiently long random number with Crypto and store it in a unique field on the object instead of using encryption. Having to put in the extra field is a disadvantage, but the advantage is that you don't need to manage a key. @RobertSösemann – IllusiveBrian Apr 29 at 23:27
1

Take a look at the External Identity license. It's designed for high-volume customer-facing webapps/use cases; the entry-level tier has very reasonable pricing (I'd say it's downright cheap). With External Identity it's likely that you will still need to roll your own pages but all identity services are available out of the box so you don't need to reinvent the wheel.

  • Would this license work with sites and existing Visualforce pages? How would users with license be created? Through a self service registration? – Robert Sösemann Apr 29 at 18:09
  • 2
    It does work with sites and communities. In fact, the External Identity user is a Community-scoped entity. Existing VF pages - it depends on what they do. Users are created via the usual means (API). It can be self-reg with your own VF page fronting that process. – identigral Apr 29 at 21:41

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.