For the remote components of a provider-hosted SharePoint Add-in to interact with SharePoint using OAuth, the add-in must first register with the Azure ACS cloud-based service and the SharePoint App Management Service of the tenancy. The registration involves creating new Client ID/Secret and other add-in specific details. After you register your add-in, it has an add-in identity and is a security principal, referred to as an add-in principal. When you install your add-in, SharePoint administrators can retrieve information about that particular add-in principal. The Client ID/Secret values need to be entered in configuration file of the application. Anyone who has access to the file system of the config file location can read these values. Using these values, they can build their own application and do anything in the SharePoint they want to (though its only restricted to app permissions defined for the app principal). This can become a big security threat especially if the app is given app-only policy permission.
This is a governance problem. Any organization need to have well defined governance on the deployment process, person responsible in making the changes in the configuration file and so on. If the config file is not well protected enough, it can become a problem. To address this scenario, we need to secure the app principle itself, so that even if someone gets access to these principles they shouldn't be able to do anything with it. The idea is to encrypt the key values using Triple-DES algorithm at Machine level. Using the encrypted value generated in one machine we can't decrypted the value in another machine, it has to be decrypted in the same machine. When an application calls the DPAPI encryption routine, it can specify an optional secondary entropy ("secret" bytes) that will have to be provided by an application attempting to decrypt data.
The solutions consists of 2 parts - Encryption (Generated using an Exe application) and Decryption (Used in the actual add-in application);
- Enter the Client ID or the Secret value in Client ID/Secret text box.
- Entropy key is optional field.
- Choose the scope as Local Machine (this is the default value)
- Click Encrypt button to get the encrypted text value and hit copy text to copy the values.
To validate the encrypted text, without altering any values, click the Decrypt button and you should see the original value of the ID/Secret given.
If the value is tampered or if you try to use the encrypted text value in a different machine, the decryption will fail.
The encrypted value is stored in the configuration file. The add-in application uses EncryptionUtility class DecryptStringWithDPAPI method to get the decrypted value. For e.g. in the TokenHelper.cs of an Add-In application, to get the actual value of Client Secret, here is the code;
private static SecureString stringClientSecret = EncryptionUtility.DecryptStringWithDPAPI(WebConfigurationManager.AppSettings.Get("ClientSecret")) ;
private static readonly string ClientSecret = EncryptionUtility.ToInsecureString(stringClientSecret);
The complete solution can be downloaded here - https://github.com/OfficeDev/PnP/tree/master/Solutions/Governance.AddInSecurity