Securing CloudPages with SSJS in Salesforce Marketing Cloud
If you ever wanted to restrict access to a landing page or an endpoint created using a CloudPage, I’ve got two options for you, that only require a short code snippet and work as a simple way to govern who is able to access your page.
IP Address Whitelisting
Restricting access based on IP addresses is pretty easy and if your landingpage is supposed to be accessible only within a company/client’s network, most of the time restricting to a few IP addresses is sufficient as many companies have just a small number of public IP addresses that are shared amongst employees at a specific office location.
Furthermore, this solution also works for processing endpoints that are called from specific servers only. In that case, this can be combined with the next approach that uses API keys and secrets to restrict access.
The code below is an example for IP address filtering, where all the allowed IP addresses are contained in the “allowedIPs”-array.
API Secret/Key verification for processing endpoints
This solution isn’t applicable for regular landingpages you visit using your webbrowser, as it is designed for processing endpoints created using CoudPages. The code verifies if the host sending a request to your CloudPage passes the correct credentials that are key/value pairs within the “allowedCredentials”-object in the example below. If there is a mismatch an error is returned, otherwise the processing continues.
In order to have an even more solid solution in place, you can also combine this method with whitelisting IP addresses like above.
The above is just a minimal example for a POST-Endpoint. To further enhance it, you could store encrypted versions of the API keys and secrets within the source code and decrypt them on the fly using encryption keys stored in Marketing Cloud’s “Key Management” feature. Unfortunately this isn’t possible with pure Server-Side JavaScript, so you’d have to mix SSJS with AMPscript code to achieve this.
An alternative enhancement could be storing the API keys and secrets within a data extension and loading them in your CloudPage. However, this is more of a scaleability improvement as adding further credentials is easier and doesn’t require code changes.
If you don’t want to send the api secret and key in the payload, this snippet can easily be modified to transmit them in the request headers for example.
Note: It isn’t best practice to use CloudPages to do heavy lifting and provide an extensive API, so please make sure you do lightweight processing and only stuff that makes sense within Salesforce Marketing Cloud.
General tip
Always make sure you have a SSL certificate configured for CloudPages in your account, so the transmission between the client and the CloudPage is encrypted. If this isn’t set up yet, contact your account executive in order to enable it. Note: If not already included in your contract, this feature comes at an additional charge.
Further reading
- Marketing Cloud Developer Documentation - Server-Side JavaScript
- Marketing Cloud Developer Documentation - Use Server-Side JavaScript with AMPscript
- Marketing Cloud Documentation - Key Management
Disclaimer / Comments
This isn’t meant as a high security measure, so don’t expose highly sensitive data or critical function via this or any other CloudPage!
Salesforce’s recommendation for entire data kept in Marketing Cloud is as follows:
NEVER use Marketing Cloud to transmit or store the following types of data:
Government-issued identification numbers, including (but not limited to):
- Social Security numbers
- Passport numbers
- Drivers license numbers
Any financial account numbers, including (but not limited to):
- Credit or debit card numbers
- Bank account numbers
- Any other similar identifiers as defined by the Payment Card Data Security Standards
If you are familiar with JavaScript, but not with Server-Side JavaScript in Salesforce Marketing Cloud, parts of the code examples might seem a bit inefficient/complicated, but this is due to the fact that SSJS only supports ECMAScript 3 and even some polyfills don’t work.