Resource Page for Jaipur Developer Festival session Publishing your app on Appexchange
Link to slide deck Publishing your app on Appexchange – Sagar Pareek
1. Storing Secrets –
What is it? : Sensitive data is exposed to user.
Remedy: Use protected custom settings.
Create custom settings with private as visibility.
Name it App Custom Settings.
Make sure setting type is List.
Create a custom object named Integration Setting
Name field should be of Auto Number ( I-{00000} )
Create 3 custom fields
Username
Password
Endpoint URL
Trigger Code –
/* Created By: Sagar Pareek Description: This trigger replaces the password with asteriks and saves the password in protected custom settings mapped with username. */ trigger IntegrationSettings on Integration_Settings__c (before insert, before update) { if (trigger.isBefore){ // Map to be checked against for the existence of a Custom Setting for a User mapuserToCustomSetting = new map (); // Lists for new, updated, and existing settings. list newSettings = new list (); list updateSettings = new list (); list existingSettings = [SELECT Id, Name, Password__c FROM App_Custom_Settings__c ORDER BY CreatedDate LIMIT 25]; list validApplicationSettings = new list (); // Populate the map based on the above query's results - keyed by the Username (name contains username) if (!existingSettings.isEmpty()){ for (App_Custom_Settings__c s : existingSettings){ userToCustomSetting.put(s.Name,s); } } for (Integration_Settings__c stg : trigger.new){ if (stg.Password__c != null && stg.Password__c != '' ){ // Inserts are easier - as long as the Password was provided, we'll add it if (trigger.isInsert) validApplicationSettings.add(stg); // We'll make sure the old and new Password values don't match and aren't udpated to the "masked" value else if (trigger.isUpdate) if (stg.Password__c != '********' && stg.Password__c != trigger.oldMap.get(stg.id).Password__c) validApplicationSettings.add(stg); } } if (!validApplicationSettings.isEmpty()){ for (Integration_Settings__c stg : validApplicationSettings){ // Do any Custom Settings exist for this User? If so, update. Otherwise, create. if (userToCustomSetting.containsKey(stg.Username__c)){ userToCustomSetting.get(stg.Username__c).Password__c = stg.Password__c; updateSettings.add(userToCustomSetting.get(stg.Username__c)); } else{ newSettings.add(new App_Custom_Settings__c(Name = stg.Username__c, Password__c = stg.Password__c)); } // Replace the Password stg.Password__c = '********'; } // Do inserts and updates if (!newSettings.isEmpty()) insert newSettings; if (!updateSettings.isEmpty()) update userToCustomSetting.values(); } } }
Force.com Security Scan Report
Link to force.com security scan report
Sample ZAP Report
Reporting False Positives in ZAP report
Link to False positive documentation
On Passing your review –