Security checklist
Describes common security issues for websites.
(Thanks to Daniel Ovaska for providing the foundation for this checklist.)
This topic provides an overview of common security issues to be aware of when building websites.
Background
Optimizely provides a flexible and granular user or role-based authorization security model that reflects best practices widely employed by enterprise-level platforms. You can control individual access through Optimizely's standard authentication and authorization mechanisms.
You can enforce user and role permissions to any website section and content level, including products, pages, and blocks. Based on user or group permissions, you can also secure standard CMS navigation and UI elements.
Using the Optimizely user interface, administrators can create users, groups, and roles to grant permissions to content items, pages, types of pages, blocks, media, properties, files, folders, and language variations. The platform can also inherit roles and permissions from a role membership provider such as Microsoft's Membership and Role Provider model.Â
Access to editing is administered by Optimizely Content Management System (CMS) admin users, who can grant editing access to groups. In addition, you can associate permissions with properties to ensure that only the allowed tabs and authors can fill properties during the editing experience.
Optimizely enables templates to be shared across sites, including styles and branding if desired. Once created, you can apply templates with permission only to be visible to certain CMS users/groups. See Security for more details.
Checklist
Consider the suggestions below to make your site as secure as possible.
- Use HTTPS
Without HTTPS, you are open to many man-in-the-middle (MITM) attacks. Do not release a site without it. Use it on the entire site and not only on the logged-in part. - Secure edit and admin views
For the strongest security, use a separate editor server. Someone cannot hack the public server if it does not have publishing capabilities. See option 2 in the blog post Server Architecture Options for Optimizely .
Shut down edit mode on the public web front:
<configuration>
...
<location path="episerver">
<system.web>
<authorization>
<deny users="*"/>
</authorization>
</system.web>
</location>
If you cannot have a separate editor server, choose hard-to-guess custom URLs for util and cms and force your editors to use strong passwords.
Another option instead of a separate editor server is to use IP restrictions for the relevant directories to lock the server down:
<system.webServer>
<security>
<ipSecurity allowUnlisted="false"denyAction="NotFound">
<add allowed="true"ipAddress="123.456.0.0"subnetMast="255.255.0.0"/>
</ipSecurity>
</security>
</system.webServer>
- Validate user input
Validate forms of user input against an allowlist (with valid characters) on the server side. You can, for example, use a regular expression to check that the string from the users contains normal characters only. If you are using user profile pages, double-check that these are validating input correctly since they may be targeted. If you need country-specific allowlists, store the regular expression as a multi-site setting.
Here are a few examples of functions that clean up the user input by regex:
public static string ToOnlyAlphaNumericInput(this string input) {
if (input == null) {
return null;
}
return Regex.Replace(input, @ "[^\w]", string.Empty);
}
public static string ToOnlyNormalTextInput(this string input) {
if (input == null) {
return null;
}
return Regex.Replace(input, @ "[^\w\.@!? ,/:+()'´-]", string.Empty);
}
- Validate querystring parameters
Similar to the one above; however, easier to forget but no less important. - HTML encode all output
This is especially important for data from other systems or user input to avoid JavaScript cross-site scripting (XSS) attacks. If you are using MVC, use the standardModel
syntax and avoidHTML.Raw
as much as possible. - Lock down web services and handlers
Optimizely handles security for content out-of-the-box, but you should check your solution for other access points, such as web services, web APIs, and handlers, and secure them or validate input. - Lock down plugins and other .NET files
Check if you have admin or editor plugins, regular aspx files, and similar, and secure them by adding a location tag inweb.config
and restricting it to a certain role. - Secure cookies
For an HTTPS site, you should mark your session cookies and authentication cookies as secure, which requires a change in theÂweb.config
and you may need to have a few lines of code in the end request event inglobal.asax
to handle the authentication cookie as well. See http://stackoverflow.com/questions/3428556/authcookie-not-secure-in-global-asax.
<configuration>
<system.web>
<httpCookies requireSSL="true" />
- Turn off detailed errors and set compilation mode to release (debug= "false" in web.config)
Inweb.config
, setÂclientResources debug
tofalse
in the<episerver.framework>
section. - Avoid click-jacking attacks
Add a response header for X-Frame-Options:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
- Restrict editors
Give them the least access rights needed and avoid creating shared accounts. If something goes wrong, you want to know who did what. - Remove test users
Delete all admin accounts used during development before launch. - Use a service account for scheduled jobs and similar
The developer uses their account instead of creating a separate service account to run scheduled jobs and uses a specific service account for tasks like these. - Check that your search result page (SRP) never displays secured content
Ensure you do not display excerpts of secured content to anonymous users on the search result page. - Filter your lists for access rights
If you list content in any way by usingGetChildren
orFindPagesByCriteria
in the background, filter your list for access rights before displaying them. The CMS controls do this, but if you use custom code to render your lists or menus, you must solve this problem to avoid showing restricted content. - Move your log files
Having your log files in the web root is not a good idea from a security point of view. CMS has log4net as its logging tool; by default, log files end up in the web root if you turn on logging. Ideally, they should be on a separate hard drive (because too large log files may crash the website). - File access rights
Double-check that your file access rights are correct and that no one has added full access rights for everyone when troubleshooting. Check this URL if you are unsure:Â Understanding Built-In User and Group Accounts in IIS 7. - Secure your service layer
For websites that are more application oriented, it is wise to secure your service layer so that some functions are only available to certain roles, for example, delete user can only be run by someone logged in as administrator. It is easy to hide the button for this in the presentation layer, but a more secure way is to add it above your service layer. One way of implementing this is using custom attributes and AOP. - Secure your data layer
Make sure you use an Object or Relational Mapping (ORM) framework like Entity Framework (EF) that does not allow SQL injections and that you never string concatenate an SQL statement together. If you run SQL-stored procedures, it might also be worth checking those for string concatenation. - Double-check your caching strategy
Make sure you never cache non-public content. For example, suppose you cache a menu (filtered on access rights) and go to the site with an admin user followed by an anonymous user. In that case, you may display menu items to the anonymous user that only admins should see. Normally, you do not need to cache Optimizely content lists if you useGetChildren
;Â Optimizely does that for you. - Secure your Virtual Path Providers (VPPs)
Do you check access rights on folders that you want? Someone might have switched the flagbypassAccessCheck="false"
. - Secure your scheduled jobs
Suppose your scheduled jobs do not work on your production site. In that case, it may be because scheduled jobs run as your current user when you click Start manually in the admin view but as an anonymous user when you run them automatically. If the anonymous access rights are insufficient, you must log in programmatically to execute the job as a specific user. See Magnus Rahl's blog post Run a scheduled job as a specific role. If you run the job as an admin, just make sure you know what you are doing. If you are not careful, you might end up sending out restricted information. - Performance
Although performance is separate, bad performance can also kill a website. Check your IIS logs to find slow pages, optimize them, and add load balancing if needed. Remember that this performance issue applies to components in your solution, including the SQL server, DNS, SSO, and so on. - Email is not a secure channel
Never send passwords and similar in email. Send a temporary link instead. - Remove unused membership providers
Remove your Windows membership provider if you do not use it. - Turn off detailed error messages for Windows Communication Foundation (WCF)
<configuration>
...
<system.serviceModel>
...
<behaviors>
<serviceBehaviors>
...
<serviceDebug includeExceptionDetailInFaults="false"/>
- Prevent cross-site forgery
Use the[ValidateAntiForgeryToken]
attribute in the MVC controller for post actions and theÂ@Html.AntiForgeryToken()
in your views. See this blog post: Prevent Cross-Site Request Forgery (CSRF) using ASP.NET MVC's AntiForgeryToken() helper. - Require strong passwords
Long passwords beat complex passwords. You should use a minimum of nine characters, preferably more. The password rules are easy to configure on your membership provider inweb.config
. See Authentication and authorization. - Check your SSL certificate
Old versions of protocols and algorithms are vulnerable to attacks. Use SSL Server Test (for instance) to check if you are using the latest versions without known security holes.
Updated 8 months ago