Continuing from my previous post for securing the Citrix ADC to score an A+ via Qualys’ scan:
Securing Citrix ADC (formerly known as NetScaler VPX) to score A+ rating on SSL Labs - February 2020
http://terenceluk.blogspot.com/2020/02/securing-citrix-netscaler-vpx-to-score.html
… I would like to demonstrate how to score an A on the Security Headers (http://securityheaders.com/) scan.
***Before I begin, note that I am scoring an A and not A+ because I have yet to determine how to configure the Content-Security-Policy without two directives that caps the score at an A without breaking the logon portal. I will update this post in the future when I am able to determine how to get around it.
Without any additional configuration, a newly published Virtual Server for Citrix Virtual Apps Desktops published by a Citrix ADC with the configuration in my previous post typically scores a C or lower:
… with the following headers that are identified as to be missing and need to be addressed:
Content-Security-Policy - https://scotthelme.co.uk/content-security-policy-an-introduction/
Referrer-Policy - https://scotthelme.co.uk/a-new-security-header-referrer-policy/
Feature-Policy - https://scotthelme.co.uk/a-new-security-header-feature-policy/
The steps to remediate these issues are to create new Rewrite Actions to insert the headers, bound them to Rewrite Policies, and finally to bound them to the appropriate internet facing virtual server. I will demonstrate this with the same Citrix Gateway Virtual Server I used in the Qualys example:
**Note that the configuration for each Security Header in the examples below can and should be customized based on the requirements of the published virtual server. Please review the links I included above for each header and ensure that you understand the options and what they are used for so you can better tweak the rewrite action parameters.
Adding the Content-Security-Policy header
The rewrite action I will be using for the Content-Security-Policy header will be as follows:
add rewrite action rw_act_insert_Content_Security_Policy insert_http_header Content-Security-Policy "\"default-src \'self\' ; script-src \'self\' \'unsafe-inline\' \'unsafe-eval\' ; style-src \'self\' \'unsafe-inline\' \'unsafe-eval\'; img-src \'self\' data:\""
"default-src 'self' ; script-src 'self' 'unsafe-inline' 'unsafe-eval' ; style-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data:"
**Note that if you remove the directives 'unsafe-inline' 'unsafe-eval' you can score an A+ from the scan but it also renders the Citrix portal unable to load.
The rewrite policy I will be binding the rewrite action will be as follows:
add rewrite policy rw_pol_insert_Content_Security_Policy "HTTP.RES.HEADER(\"Content-Security-Policy\").EXISTS.NOT" rw_act_insert_Content_Security_Policy
HTTP.RES.HEADER("Content-Security-Policy").EXISTS.NOT
The last step to bind the rewrite policy to the virtual server will look as such:
bind lb vserver <virtual server> -policy rw_pol_insert_Content_Security_Policy -type RESPONSE -priority 130 -gotoPriorityExpression NEXT
Note the Rewrite Policy under the Response Policies heading:
Be aware of the following configuration in the screenshot above:
Priority – The value will be dependent on what other rewrite policies are currently configured for this VPN Virtual Server.
GOTO Expression – Note that I have configured this value to NEXT instead of END because I will be adding more Rewrite actions that will have a lower priority (higher Priority number) this this VPN Virtual Server and if I configure the value as END then the rest will not be applied.
Executing the Security Headers scan should not find the Content-Security-Policy header present:
One of the issues I’ve encountered when inserting this header into a portal integrated with a DUO MFA solution was that it was no longer able to redirect my login requests to the 2FA page. If you encounter such an issue then please refer to one of my previous posts here:
Configuring Content-Security-Policy HTTP Response Header on Citrix ADC for Citrix Apps and Desktops with DUO integration
http://terenceluk.blogspot.com/2020/02/configuring-content-security-policy.html
Adding the Referrer-Policy header
The rewrite action I will be using for the Referrer-Policy header will be as follows:
add rewrite action rw_act_insert_Referrer_Policy insert_http_header Referrer-Policy "\"strict-origin-when-cross-origin\""
"strict-origin-when-cross-origin"
The rewrite policy I will be binding the rewrite action will be as follows:
add rewrite policy rw_pol_insert_Referrer_Policy "HTTP.RES.HEADER(\"Referrer-Policy\").EXISTS.NOT" rw_act_insert_Referrer_Policy
HTTP.RES.HEADER("Referrer-Policy").EXISTS.NOT
The last step to bind the rewrite policy to the virtual server will look as such:
bind lb vserver <virtual server> -policyName rw_pol_insert_Referrer_Policy -type RESPONSE -priority 140 -gotoPriorityExpression NEXT
As with the previous rewrite policy, be aware of the following configuration in the screenshot above:
Priority – The value will be dependent on what other rewrite policies are currently configured for this VPN Virtual Server.
GOTO Expression – Note that I have configured this value to NEXT instead of END because I will be adding more Rewrite actions that will have a lower priority (higher Priority number) this this VPN Virtual Server and if I configure the value as END then the rest will not be applied.
Adding the Feature-Policy header
The rewrite action I will be using for the Content-Security-Policy header will be as follows:
add rewrite action rw_act_insert_Feature_Policy insert_http_header Feature-Policy "\"vibrate \'self\'; sync-xhr \'self\' https://<portalURL.com\""
"vibrate 'self'; sync-xhr 'self' https://portalURL.com"
The rewrite policy I will be binding the rewrite action will be as follows:
add rewrite policy rw_pol_insert_Feature_Policy "HTTP.RES.HEADER(\"Feature-Policy\").EXISTS.NOT" rw_act_insert_Feature_Policy
HTTP.RES.HEADER("Feature-Policy").EXISTS.NOT
The last step to bind the rewrite policy to the virtual server will look as such:
bind lb vserver <virtual server> -policyName rw_pol_insert_Feature_Policy -type RESPONSE -priority 150 -gotoPriorityExpression END
As with the previous rewrite policy, be aware of the following configuration in the screenshot above:
Priority – The value will be dependent on what other rewrite policies are currently configured for this VPN Virtual Server.
GOTO Expression – Note that I have configured this value to End instead of NEXT because I this was the last Rewrite action with no other one following.
Adding the Content-Security-Policy, Referrer-Policy, and Feature-Policy header all together
The following are all of the commands bundled into one. Please modify the virtual server and site name as required:
add rewrite action rw_act_insert_Content_Security_Policy insert_http_header Content-Security-Policy "\"default-src \'self\' ; script-src \'self\' \'unsafe-inline\' \'unsafe-eval\' ; style-src \'self\' \'unsafe-inline\' \'unsafe-eval\'; img-src \'self\' data:\""
add rewrite policy rw_pol_insert_Content_Security_Policy "HTTP.RES.HEADER(\"Content-Security-Policy\").EXISTS.NOT" rw_act_insert_Content_Security_Policy
bind lb vserver citrix.ccs.bm -policy rw_pol_insert_Content_Security_Policy -type RESPONSE -priority 130 -gotoPriorityExpression NEXT
add rewrite action rw_act_insert_Referrer_Policy insert_http_header Referrer-Policy "\"strict-origin-when-cross-origin\""
add rewrite policy rw_pol_insert_Referrer_Policy "HTTP.RES.HEADER(\"Referrer-Policy\").EXISTS.NOT" rw_act_insert_Referrer_Policy
bind lb vserver citrix.ccs.bm -policyName rw_pol_insert_Referrer_Policy -type RESPONSE -priority 140 -gotoPriorityExpression NEXT
add rewrite action rw_act_insert_Feature_Policy insert_http_header Feature-Policy "\"vibrate \'self\'; sync-xhr \'self\' https://<portalURL.com\""
add rewrite policy rw_pol_insert_Feature_Policy "HTTP.RES.HEADER(\"Feature-Policy\").EXISTS.NOT" rw_act_insert_Feature_Policy
bind lb vserver citrix.ccs.bm -policyName rw_pol_insert_Feature_Policy -type RESPONSE -priority 150 -gotoPriorityExpression END
With the configuration applied, you should now see a score of A from the Security Headers scan: