Developers that build web applications know that many factors go into protecting a site from hackers. Whitelisting input, ensuring proper authentication features, and building frontend and backend code that checks for certain attacks are just a few ways developers can protect web applications, but using web server headers are also an effective way of protecting from cross-site scripting (XSS), man-in-the-middle (MitM) attacks and clickjacking.
Some web browsers (mainly Internet Explorer and Chrome) analyze the content of a web page and use the detected asset type of an object to render it on the user’s desktop. This phenomenon is called MIME (Multipurpose Internet Mail Extensions) sniffing. The intention is to read and render web page assets even if the developer has incorrectly labeled them, but it can be a cybersecurity risk and leave your web pages vulnerable to cross-site scripting (XSS) attacks.
The “X-Content-Type-Options: Nosniff” header is not supported by all browsers, but adding this to the web application’s server response will protect users that work with Chrome or Internet Explorer. The vulnerability exists when the application allows users to upload content that’s then rendered later. Your application might have filters to block certain content types (for instance, it could filter out HTML file uploads), but attackers will test for XSS vulnerabilities by changing a malicious file’s extension (e.g. from HTML to JPG) and upload it. When the browser uses MIME sniffing, the HTML file disguised as a JPG is first downloaded by a user. Then, the browser detects that the content should be rendered as HTML instead of JPG and allows the malicious script to run in the user’s browser.
With the “X-Content-Type-Options: Nosniff” header, the browser will no longer MIME sniff and will render assets based on headers sent by the server.
This header option is used on sites that have iframe HTML tags. Using this header will stop clickjacking vulnerabilities. With clickjacking, an attacker can trick users by adding an iframe to a malicious web page that loads your application. The attacker uses invisible layers that trick the user into sending commands to the application, but really they are interacting with the attacker’s site.
Clickjacking can trick the user into interacting with the attacker’s invisible layer or an invisible iframe that loads your application content. For instance, clickjacking used to be popular in blackhat online marketing where an attacker would load invisible Facebook like buttons over an application’s buttons. An attacker could have a “Play” button with invisible like buttons over the Play button. Users click “Play,” but they also click “Like” on an attacker’s page.
The infamous Adobe Flash vulnerability that gave an attacker remote control of a user’s machine used clickjacking. The attacker loaded invisible Flash settings buttons over a visible web page. A user would click buttons on the attacker’s web page, but an invisible iframe placed Flash security options over these buttons and users unknowingly changed settings on their local browser, which in turn gave the attacker control of the desktop.
You can avoid this attack by using the “X-Frame-Options: SAMEORIGIN” server header. The SAMEORIGIN directive tells the browser that only your domain can load content into an iframe. This directive is needed if you use iframes on the site, but you have two other options if you want to allow a third party (e.g. another site that you own or an affiliate) to load the site in an iframe or deny iframes altogether.
The following two header directives are also available:
- X-Frame-Options: DENY – use this option if you want to block all content from loading in an iframe.
- X-Frame-Options: allow-from https://example.com – use this option if you want to allow a third-party domain to load your site into an iframe.
CORS is often implemented when a web application calls an API over HTTP(S). As an example, using SiteA.com for your site, and SiteB.com as the domain for the API. SiteA.com makes calls to SiteB.com to retrieve information about a user. SiteA.com sends information from the user’s authentication session to query data about the user from SiteB.com. If no CORS header is used, any domain can make calls to SiteB.com and SiteB.com will return the requested data. Without CORS security, an attacker could trick a user into making a request to SiteB.com and send the information to the attacker, which in this scenario gives the attacker private data about the user account.
With the “Access-Control-Allow-Origin” header, SiteB.com can specify which domains can receive data. SiteB.com’s admin would need to set the “Access-Control-Allow-Origin” header to allow SiteA.com to make calls to the API and retrieve data. Note that this header specifies if SiteB.com will send data to SiteA.com, but SiteA.com will still be able to make calls.
A common way that developers perform CORS requests is to use the AJAZ XMLHttpRequest (XHR) object. This object performs a request without requiring a full refresh of the web page. If CORS security is used on SiteB.com, a request using XHR will return an error.
The two header options are commonly used in web applications:
- Access-Control-Allow-Origin: * — this setting is not recommended. The asterisk tells the web application that any domain can retrieve data from the target web page.
- Access-Control-Allow-Origin: https://example.com – this header tells SiteB.com that the domain “https://example.com” can retrieve data from the local site.
These three server headers will improve web application cybersecurity. It doesn’t stop every vulnerability from being exploited, but it stops some attack risks from common coding mistakes and bugs. Using these headers, you can stop XSS, CSRF, session hijacking and some attacks that use social engineering and phishing.