I recently submitted an application to the AppExchange, only to have it not pass the security check due to "Insecure Storage of Sensitive Data Vulnerability." The problem is that my app accesses an external API, for which it has its own API Secret and API Key. These are static, and specific to the Salesforce App- they will be the same for all users, all installations, etc.

Perhaps stupidly, I stored them as private properties of the class that uses them.

private static String apiSecret = 'superS3|<R37';
private static String apiKey = 'sameHerebutdifferent';

It is a Managed app, so users cannot see them. As such, I am puzzled as to 1. why this is insecure and 2. how better to store these values, given that we are apparently operating under the assumption that having them in the text of the class itself is insecure.


1 Answer 1


Besides the other question, with its accepted answer, see Secure Coding Storing Secrets for additional information. It's basically the same information summarized in that answer, but includes much more information.

In summation, you should use protected custom settings, encrypted text fields, or Apex Crypo functions. Also, avoid storing the data in view state, using debug statements, or basically ever letting it appear in a browser's memory/cache. Query it on demand, decrypt it, use it, and discard it immediately by setting any variable it is stored in to null.

  • Alright, I think Protected Custom Settings are the best option here, since it means there is no need to go through encryption/decryption. Just query it directly each time and put it in. Thank you. Commented Aug 13, 2014 at 2:00
  • There is one problem here- how do I get the secret into the Protected Custom Setting securely? Currently I have the PostInstall script create the setting with the key in it, but that was just rejected by the security review. The same key and secret are used by all users of the app, and they should never know what they are, so the example Salesforce gives of having the user enter them and store them only as transient does not apply. Commented Aug 25, 2014 at 16:36
  • That's odd. Do install scripts have to be global or something that would force the key to be exposed?
    – sfdcfox
    Commented Aug 25, 2014 at 21:08
  • Yes, they are required to be global. Commented Aug 27, 2014 at 0:55
  • That's just silly. Could you dispatch a batch class or future method? Those can be public.
    – sfdcfox
    Commented Aug 27, 2014 at 1:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .