1. Use SSL
Encryption of data in transitIf your site serves up private information, use SSL.
Use SSL, not just for the login page of your website but throughout the website. Typically, authentication credentials are stored as HTTP Cookies that are transmitted with every HTTP request. It makes no sense to grant these authentication cookies securely and later transport them insecurely for all the hackers to see (by using Network sniffers).
Use of SSL is the easiest security measure you can take. The effectiveness of the rest of the security measures described below, directly or indirectly, depend upon communicating website data over a secure communication channel.
Be sure that all security updates have been applied to your Web server. For example, if you are using OpenSSL you should close the Heartbleed Virus loophole. See: https://www.openssl.org/news/secadv_20140407.txt
Be sure that all security updates have been applied to your Web server. For example, if you are using OpenSSL you should close the Heartbleed Virus loophole. See: https://www.openssl.org/news/secadv_20140407.txt
2. Guard against SQL Injection Attacks
Execution of malicious SQL statements against the databaseIf your code forms SQL queries dynamically by directly concatenating values entered by the user, your application may be vulnerable to SQL injection attacks.
Let's say you allow users to lookup whether they are already registered on your website by entering their email address.
Behind the scenes, your code forms the following SQL query.
string sqlUserExists = "SELECT * FROM RegisteredUsers WHERE EmailAddress='" + userEnteredAddress + "'";
If the user enters, someone@xyz.com for userEnteredAddress, you get the following SQL query.
SELECT * FROM RegisteredUsers WHERE EmailAddress='someone@xyz.com';
So far, so good. But what if the user enters the following text for userEnteredAddress:
badguy@xyz.com';delete from RegisteredUsers --
The corresponding dynamic SQL becomes the following statement that deletes all users from the RegisteredUsers table.
SELECT * FROM RegisteredUsers WHERE EmailAddress='badguy@xyz.com';delete from RegisteredUsers --';
Mitigations
- Clean the user entered values that you use in dynamic SQL (for example, using RegEx). This is not the best way to guard against SQL injection attacks since the your code is responsible for cleaning up values everywhere in the code and will likely miss certain loopholes.
- Use Parameterized Queries (see SqlCommand.Parameters)
- Use Stored Procedures
- Use an ORM tool
3. Guard Against Cross Site Scripting (XSS)
A malicious script is executed from victim's browser to steal sensitive information or to cause harm to other sites using victim's browserModern websites use client side scripts (such as JavaScript) to enhance user experience. In an XSS attack, these scripts are manipulated to do malicious things such as alter DOM elements of the web page, send sensitive information to hacker sites, and to steal authentication credentials. There are several ways a hacker injects malicious scripts.
I. Passes malicious script as part of the query string. Many web applications directly use the contents of the query string to generate Web forms HTML and returns them as part of Web pages. If the contents the query string contain valid (and malicious) HTML tags and scripts, they are returned back to the Browser as part of the form and executed causing a security breach. This is an example of a reflected malicious script.
II. Injects malicious scripts into the database that returns information to the user's Web browser (see SQL injection attack description above). For example, a malicious script is inserted into one of the database columns of an entity. When that entity is displayed in user's Web browser, the malicious script is executed. This is an example of a persistent malicious script.
III. Enters input values that contain malicious script which in turn is unsafely processed by our client-side scripts. For example, if our site shows an alert by echoing values entered by the user or by adding DOM elements with values obtained after parsing JSON data (with JavaScript or jQuery), we are susceptible to such attacks. Instead of entering plain text script, a hacker may enter an encoded string to further confuse our scripts.
Mitigations
- Clean data before processing or storing it. AntiXss Sanitizer is a library that provides such capabilities (Sanitizer.GetSafeHtml() and Sanitizer.GetSafeHtmlFragement()). Specify UTF-8 encoding in web.config. That way, the hacker cannot override the text encoding and the sanitizing rules are fully enforced.
- When manipulating DOM, use safe methods to set values. For example, use setAttribute to set an attribute of an element instead of directly manipulating the html() of an element.
- Remember, not all scripts are present in <script> tags. A script may be entered as part of an HTML tag (<img onClick="alert(input)"/>). Avoid such scripts if you can (for example, use jQuery instead to add click handlers; that way the scripts will be under <script/> tags and will be easier to audit).
- In ASP.NET, enable <system.web><httpRuntime requestValidationMode="2.0" /></system.web>. This instructs ASP.NET to examine input from the browser for dangerous values.
- Use safe methods to output values of a variables to a Web page. For example, in MVC use @dataVar to safely output the value of a variable to a Web page. Micrsoft.Security.Application.Encoder.HtmlEncode(input) and Json.Encode(model) are also available to encode input that contains HTML/JavaScript.
4. Guard Against Cross Site Request Forgery (CSRF)
A malicious request is executed from victim's browser using victim's credentialsHacker uses victim's authentication credentials from victim's own browser to steal information. Here's how it works.
- Victim visits and logs into their bank site.
- Without logging out, the victim knowingly or unknowingly invokes script from a malicious site (lured by an image or any link in email, or by navigating to a link on a malicious website).
- Since the victim is still logged into their bank site, the malicious code (usually a script disguised as a link to image) performs inappropriate actions on victim's bank website usually by making a background AJAX call.
Mitigations
- Use HTTP GET exclusively for retrieving information (i.e. no data updates should ever occur as a result of an HTTP GET).
- Use HTTP POST/PUT/DELETE for updates.
- For an ASP.NET Web Form, add Session.SessionID to Viewstate. Viewstate is validated by ASP.NET and is difficult to forge by the hacker.
- For ASP.NET MVC applications, use @Html.AntiForgeryToken() for each HTML form. Apply [ValidateAntiForgeryToken()] to the POST controller method.
5. Secure data at rest
Encrypt data that is stored in file system, and databases
Say a hacker gains access to the file system or database of your Web application. The hacker can do a lot of damage with the data stored by Web application.
Mitigations
- Whenever possible encrypt and then store sensitive data. This puts another layer of protection between your Web application and the hacker.
- Always store hash of passwords (instead of plain text representation). Furthermore, use a salt when creating a hash. The use of salt will thwart against a Dictionary attack.