Increase Salesforce Site security

It's quite easy to use Salesforce site to present public pages over the Internet. What about security? We won't speak about SOQL injection, Cross Site Scripting (XSS), Cross Site Request Forgery (CSRF) or any usual website security risk. This article is intended to focus on dedicated Salesforce Site risks, "by design". We will see the relationship between governor limits and security of public pages, and how someone could access items that you would not expect.

Security and governor limits

There are many platform limitations (governor limits) defined to prevent excessive consumption of platform resources. This ensure platform availability for other customers running on the same POD. On the other side, if you reach the limit, your site will be down: "If, in a given calendar month, your organization reaches 300% of its page view limit, your sites are disabled until the next calendar month begins or you purchase more page views."
The drawback is that someone can make your Salesforce site down just by pushing your site over the governor limits. How can he do this ?

Looking for a Salesforce Site

First, the "hacker" will try to get a list of available Salesforce Site. With a simple query in Google, he will retrieve a few
In this example, we were trying to target a developer edition. To identify a production Site, the attacker has to find a force.com domain, which will be in the form of http://mycompany.force.com . To identify subdomains, you can go search in Google for site:force.com or inurl:.secure.force.com. There is a solution against this: create a branded custom web address ( ex: http://www.valueinpartnershipplus.com/ - could you have identified it is running on force.com ?). It will be much more difficult to identify you are running a Salesforce Site.
You can even try to find a site from the sandbox ( inurl:.cs2.force.com ) as this can reveal other interesting information.

The limits

Governor limits are defined according to the type of Org (Developer, Enterprise, Unlimited), based on Network and CPU consumption.
EditionMaximum Number of SitesBandwidth Limit (per rolling 24-hour period per site)Service Request Time (per rolling 24-hour period per site)Maximum Page Views
Developer Edition1500 MB10 minutesN/A
Enterprise Edition251 GB for sandbox

40 GB for production

30 minutes for sandbox

60 hours for production

500,000
Unlimited Edition251 GB for sandbox

40 GB for production

30 minutes for sandbox

60 hours for production

1,000,000
An attacker can try either to target a big page (in size) and download it thousands of times (using a bot) to consume your bandwidth, or identify a page that takes a lot of time to load, which is an indicator of CPU consumption, and use the same bot to try to reach the CPU limit.
Don't try to use the CDN to reduce the pages viewed, it has no effect on this indicator as it is the sum of pages served from the server and from the cdn. For public pages (i.e. not for intranet or authenticated use), there is no lever to prevent a Denial of Service that will make you hit the page limit. Salesforce has some internal mechanisms to prevent DoS, but in case of DDoS or CSRF it's quite hard to avoid reaching the limit.
The CPU limit requires optimizing all your public pages for performance. You can identify for each page what is the cost on the server, by using Google Pagespeed tool for instance ( example ). The server cost is related to the DCL value; if greater than 0.5 sec then you have to improve your page (controller, merge fields, soql queries...). This will not avoid reaching the CPU usage limit, this will just decrease the cost per page (requiring more pages to fetch before reaching the limit).

Security and Content

When running a Salesforce Site, you will leverage the CDN and use static resources to host static items used in your pages. It is a performant approach, but this can present a new risk; anybody can retrive the full zip file, even if you are using only part of the items stored in the zip.
To retrieve a resource zip file, just do a "view-source" on the VisualForce public page. Identify a relative linked resource ( src="/resource/1234567890/ResourceName/Path/FileName.ext" where 1234567890 can be any number and the path + filename.ext a static file used in the html generated page, contained in the ziped resource file). Remove the path + filename.ext from the Url address and try to access the resulting address, this will start the download of the full zip file! You save it locally, open it and in many case you will have access to resources that are not used by the page (the administrator didn't expect you access them).
To manage this issue, ensure having resource zip files that are only hosting required static files, with no confidential information.
Inside the source code you will be able to discover valid orgId, UserId, portalId and various technical info... just be creative with this!