Skip to main content

Step up your HTTP security header game with NetScaler Rewrite Policies



There are a number of HTTP response headers that exist to increase web site security. If set properly, they can ensure that your site is less exposed to many common web vulnerabilities. By no means are these descriptions exhaustive, so I have included some references that can provide a more in-depth explanation at the bottom of each section. I'd also like to give a shout-out to the OWASP Secure Headers Project and Scott Helme of securityheaders.com - thank you!

Note: Screenshots are from a NetScaler VPX 12.1 - if you are running a different version, the screenshots may look different, but the logic is the same. So that I have something to bind these policies to, I've also already created a load-balancing virtual server named lb_web_ssl and a Service Group for two TurnKey LAMP servers on the back-end.

X-Frame-Options

The X-Frame-Options header is designed to guard against clickjacking (an attack where malicious content is hidden beneath a clickable button or element on a web site) by preventing a site's content from being displayed in other sites. There are three possible directives for this setting - DENY, SAMEORIGIN, and ALLOW FROM [domain]. We'll be using the SAMEORIGIN directive, so that only frames that originate from the same page that they are being displayed are allowed.


Create the Rewrite Action within the NetScaler GUI:




Once the Action is created, create the Rewrite Policy as shown:




From there, you can just bind your newly created Rewrite Policy to the LB vserver as a Response policy. Make sure you select the "NEXT" Goto Expression instead of  "END", since we'll be adding more policies after this one.

 add rewrite action rwact_insert_xframe insert_http_header X-Frame-Options "SAMEORIGIN"  
 add rewrite policy rwpol_insert_xframe HTTP.REQ.IS_VALID rwact_insert_xframe  
 bind lb vserver lb_web_ssl -policyName rwpol_insert_xframe -priority 100 -gotoPriorityExpression NEXT -type RESPONSE  

References: 
https://tools.ietf.org/html/rfc7034
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options

X-XSS-Protection


The X-XSS-Protection header controls the Cross-Site-Scripting filter in your computer's web browser. Setting a value of "1" will enable the filter and instruct the browser to sanitize the page if a XSS attack is detected. The "mode=block" value will cause the browser to prevent the rendering of the page entirely rather than simply sanitizing the page.


Configure Rewrite Action:



Configure Rewrite Policy:



CLI commands:


 add rewrite action rwact_insert_xss_header insert_http_header X-XSS-Protection "\"1; mode=block\""  
 add rewrite policy rwpol_insert_xss_header true rwact_insert_xss_header  
 bind lb vserver lb_web_ssl -policyName rwpol_insert_xss_header -priority 110 -gotoPriorityExpression NEXT -type RESPONSE  

References:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection


X-Content-Type-Options


When a client (such as web browser) encounters a page with a missing MIME type (a way for sites to indicate the type of content that is being displayed) or one it believes to be incorrect, it can perform MIME type sniffing, where it attempts to "guess" the MIME type. The X-Content-Type Options header's function is to specify that the MIME types shouldn't be changed by the browser.


Configure Rewrite Action:



Configure Rewrite Policy:



CLI commands:

 add rewrite action rwact_insert_content_type_header insert_http_header X-Content-Type-Options "\"nosniff\""  
 add rewrite policy rwpol_insert_content_type true rwact_insert_content_type_header  
 bind lb vserver lb_web_ssl -policyName rwpol_insert_content_type -priority 120 -gotoPriorityExpression NEXT -type RESPONSE  

References:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#MIME_sniffing
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types

X-Permitted-Cross-Domain-Policies

A cross-domain policy is an XML file that determine what sort of information a site is allowed to fetch from other domains (for example, .swf or .pdf files, but not necessarily limited to those file types). The possible values for this header are as below:

Source: https://owasp.org

The value that is correct for your site will depend heavily on the way that the site is designed. For my lab environment, I'll be setting the value to "none".


Configure Rewrite Action:



Configure Rewrite Policy:


CLI commands:


 add rewrite action rwact_insert_xdomain_policies insert_http_header X-Permitted-Cross-Domain-Policies "\"none\""  
 add rewrite policy rwpol_insert_xdomain_policies true rwact_insert_xdomain_policies  
 bind lb vserver lb_web_ssl -policyName rwpol_insert_xdomain_policies -priority 130 -gotoPriorityExpression NEXT -type RESPONSE  

References:
https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#xpcdp
https://www.adobe.com/devnet-docs/acrobatetk/tools/AppSec/xdomain.html

Referrer-Policy

When a user clicks on a link to another site, the Referer header conveys information to the destination site about the source URL of the request. Typically, this information is used for site analytics and tracking. The Referrer-Policy specifies what type of information is sent. There are several different options that suit many different use cases - check out the Mozilla Developer Network link below for a list of the options and also some helpful examples of the types of information that is sent based on the different options. I'll be setting the "no-referrer" value, which omits the Referer header from the HTTP request entirely.

Configure Rewrite Action:



Configure Rewrite Policy:


CLI commands:


 add rewrite action rwact_insert_referrer_policy insert_http_header Referrer-Policy "\"no-referrer\""  
 add rewrite policy rwpol_insert_referrer_policy true rwact_insert_referrer_policy  
 bind lb vserver lb_web_ssl -policyName rwpol_insert_referrer_policy -priority 140 -gotoPriorityExpression NEXT -type RESPONSE  

References:
https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#rp
https://www.w3.org/TR/referrer-policy/
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy

HTTP Strict Transport Security (HSTS)

HTTP Strict Transport Security is a way for sites to specify that clients can only browse the site via HTTPS. The "max-age" directive determines how long a client should remember that a site should only be accessed via HTPS. The optional includeSubDomains directive determines (surprise!) whether or not the site's subdomains fall under the same rule and are served by HTTPS only. Finally, the "preload" directive specifies your desire to be included in Google's HSTS preload list. You can test your site's eligibility for the HSTS preload list by visiting https://hstspreload.org and putting in your domain. If you're not eligible, the site gives you remediation steps as well.

Note: As of version 12.0, you can also accomplish this via SSL Policies instead of Rewrite Policies - please see https://support.citrix.com/article/CTX224172 for more information.

Configure Rewrite Action:



Configure Rewrite Policy:



CLI commands:

 add rewrite action rwact_insert_hsts insert_http_header Strict-Transport-Security "\"max-age=31536000; includeSubDomains; preload\""  
 add rewrite policy rwpol_insert_hsts true rwact_insert_hsts  
 bind lb vserver lb_web_ssl -policyName rwpol_insert_hsts -priority 150 -gotoPriorityExpression NEXT -type RESPONSE  

References:
https://tools.ietf.org/html/rfc6797
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
https://hstspreload.org

Expect-CT


The Expect-CT header is a relatively new HTTP header that allows web site owners to take advantage of the Certificate Transparency framework by rejecting connections to a site with a compromised SSL certificate -  for example, if a public CA mistakenly or maliciously issues a  certificate. When using the "enforce" directive, browsers will reject connections that do not meet the Certificate Transparency requirements; omitting the directive will result in a "report-only" configuration where violations are reported to the specified location, but not actively rejected.

Configure Rewrite Action:



Configure Rewrite Policy:



CLI commands:

 add rewrite action rwact_insert_expect-ct insert_http_header Expect-CT "\"max-age=86400, enforce, report-uri=https://example.com/ct-report\""  
 add rewrite policy rwpol_insert_expect-ct true rwact_insert_expect-ct  
 bind lb vserver lb_web_ssl -policyName rwpol_insert_expect-ct -priority 160 -gotoPriorityExpression NEXT -type RESPONSE  

References:
https://tools.ietf.org/html/draft-ietf-httpbis-expect-ct-02
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT
https://www.certificate-transparency.org/


Content-Security-Policy


The Content-Security-Policy header's primary goal is to be another layer of defense against XSS (cross-site scripting) attacks by controlling what external content is allowed to be loaded on the site. However, it can also protect you against other types of attacks by restricting which protocols are allowed to be used to load content (for example, disallowing content delivered via HTTP). There are many different directives that can be used to control what content is allowed to load - for the full list, check out the link in the references section. I'll be using the default-src, script-src, style-src, and img-src directives in my example and only allowing content to load from the site itself.

Configure Rewrite Action:


Configure Rewrite Policy:


CLI commands:

 add rewrite action rwact_insert_csp insert_http_header Content-Security-Policy "\"default-src \'self\' ; script-src \'self\' ; style-src \'self\' ; img-src \'self\' data:\""  
 add rewrite policy rwpol_insert_csp true rwact_insert_csp  
 bind lb vserver lb_web_ssl -policyName rwpol_insert_csp -priority 170 -gotoPriorityExpression END -type RESPONSE  

References:
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

Conclusion

After all of our policies have been applied, here is what your Rewrite Policy bindings should look like. Keep in mind that if you add more policies later, be sure to change the last Goto Expression to NEXT instead of END so that policy processing works as expected.




This is it, folks. the moment you've all been waiting for - has our hard work actually paid off? Is it even working? Enter securityheaders.com, which is designed to rate sites based on how well they comply with the HTTP header security standards. After applying the policies we've created above, here is the Security Headers site output:


Success!

I'd probably also remove the Server header from the HTTP response so that it obscures the fact that there's an Apache server behind the NetScaler, but it looks like it didn't affect my score, so I'm going to leave it in. 

 As I've said before, your specific site and use case may differ and will probably result in completely different values for the various directives that are outlined here. Hopefully this post will help you become familiar with what the different headers are and how their various settings will help keep your sites better protected. Thanks for reading!

Comments

Popular posts from this blog

How To: Unjoin NetApp Nodes from a Cluster

Let me paint you a word picture:

You've upgraded to a shiny new AFF - it's all racked, stacked, cabled and ready to rock. You've moved your volumes onto the new storage and your workloads are performing beautifully (of course) and it's time to put your old NetApp gear out to pasture.

We're going to learn how to unjoin nodes from an existing cluster. But wait! There are several prerequisites that must be met before the actual cluster unjoin can be done.


Ensure that you have either moved volumes to your new aggregates or offlined and deleted any unused volumes.Offline and delete aggregates from old nodes.Re-home data LIFs or disable/delete if they are not in use.Disable and delete intercluster LIFs for the old nodes (and remove them from any Cluster Peering relationships)Remove the old node's ports from any Broadcast Domains or Failover Groups that they may be a member of.Move epsilon to one of the new nodes (let's assume nodes 3 and 4 are the new nodes, in th…

NetApp ONTAP 9.3 Simulator Deployment - Part 1

I am going to be doing a few of these simulator/lab posts in an effort to set up an environment that will pave the way for future guides and blog posts. Hopefully it'll also be a good resource for folks that want to set up their own labs to test out new features and software versions. Today I'm going to show the steps required to deploy Netapp's ONTAP Simulator 9.3 on vSphere 6.5.  I'll also be doing a follow-up article that will detail the process of clustering a second node with this first one.

Note: My lab has vCenter 6.5 deployed along with a Distributed vSwitch, so the steps will be specific to that deployment. I will also assume that you already have basic networking and storage for your virtual machines in place.

Step 1: Deploying the Simulator

1. Browse out to https://mysupport.netapp.com, click on "Sign In" in the upper right-hand corner and log in using your NetApp account credentials.

2. Click on the Downloads drop-down at the top of the screen and c…

Cisco UCS Platform Emulator Installation

To continue my series of posts on building the framework for a functional lab environment, I'd like to talk about the Cisco UCS Platform Emulator (UCSPE). It is a software appliance packaged as a vSphere OVA that approximates a UCS deployment, including the networking components (a pair of switches called the Fabric Interconnects) and both blade and rackmount UCS servers (B- and C-Series, respectively). It can be a great tool for learning and becoming more familiar with the UCS platform. I will be deploying my UCSPE on vSphere 6.7 in my lab, but it should work similarly in other recent versions.

1. Start by downloading the UCS Platform Emulator OVA from https://communities.cisco.com/docs/DOC-71877 - you will need a Cisco Connection Online (CCO) login in order to begin the download. I am using version 3.1(2ePE1) of the emulator for this guide as that appeared to be the latest version available at the time of writing. Side note, I also noticed during the boot process that this versi…