Administrators who upgraded NetScaler Gateway to v14.1/b47.46 or later may have noticed a change that can affect existing authentication configurations.
Starting with NetScaler v14.1/b47.46, the Content Security Policy (CSP) response header is enabled by default for NetScaler Gateway and authentication virtual server-generated responses. Citrix introduced this as part of its security-by-default approach. CSP helps reduce browser-based attacks such as cross-site scripting (XSS) by controlling the resources a page can load and where forms are allowed to submit data.
One of the directives included in the default CSP is:
form-action 'self'
This directive tells the browser that HTML forms should only submit back to the same origin, which is a reasonable security control in many situations. The issue occurs when an authentication workflow legitimately needs to submit a form to an external service, which can occur when NetScaler is acting as the SAML Service Provider (SP) and Imprivata Web SSO is acting as the Identity Provider (IdP).
Imprivata’s documentation confirms that its SAML integration uses an IdP SSO endpoint similar to:
https://idp.cloud.imprivata.com/<tenantID>/saml2/sso/post
And specifies HTTP POST as the SAML binding for this configuration.
While this is an expected part of the SAML authentication process, NetScaler’s default CSP can prevent the browser from completing the form submission to the external IdP.
The Issue
Identifying the CSP conflict is only part of the challenge, as the authentication flow involves multiple responses that may be evaluated individually. The issue becomes visible during the NetScaler SAML authentication flow, which can be simplified as follows:
Browser │ ▼ /logon/LogonPoint/tmindex.html │ ▼ /nf/auth/doSaml?ctx=... │ ▼ POST to the Imprivata SAML endpoint │ ▼ https://idp.cloud.imprivata.com/<tenant>/saml2/sso/post
The /nf/auth/doSaml endpoint is part of the NetScaler SAML authentication workflow. During this step, the browser is instructed to submit the SAML request to the configured IdP. The response observed during troubleshooting contains a form similar to:
<html>
<head></head>
<body>
<script type="text/javascript" nonce>
window.onload = function () {
document.forms[0].submit();
}
</script>
<form action="https://idp.cloud.imprivata.com/<tenant>/saml2/sso/post"
method="post">
</form>
</body>
</html>
If the response also contains form-action ‘self’ in the CSP header, the browser rejects that form submission because the destination is outside the NetScaler Gateway origin. The browser developer console shows:
Sending form data to 'https://idp.cloud.imprivata.com/<tenant>/saml2/sso/post' violates the following Content Security Policy directive: "form-action 'self'". The request has been blocked.
At that point, the SAML configuration itself may be perfectly valid, and the browser is simply enforcing the CSP that NetScaler returned.
Why This Can Be Difficult to Troubleshoot
Several factors make this issue harder to diagnose than initially appears.
- Different responses can have different CSP headers.
It is tempting to look at /logon/LogonPoint/tmindex.html and assume that changing the CSP on that response will fix the entire authentication flow; however, it may not.
The browser makes additional requests during authentication, including /nf/auth/doSaml. Each HTTP response can have its own headers. A rewrite policy that modifies the CSP on tmindex.html does not automatically modify the CSP returned for doSaml. This distinction becomes especially important when troubleshooting SAML.
- AAA_RESPONSE matters for packet-engine-generated responses.
This is one of the most important details in the troubleshooting process. Citrix documents two response rewrite bind types for Gateway and authentication vServer-generated responses:
| Blind Type | When To Use |
|---|---|
| AAA_RESPONSE | Response generated by the packet engine. |
| RESPONSE | Response generated by Apache. |
In this scenario, the policy did not receive hits when bound with -type RESPONSE. For the doSaml response described here, the working configuration uses -type AAA_RESPONSE on the VPN vServer.
- The existing DUO example does not cover every authentication workflow.
Citrix’s CSP documentation includes an example for DUO authentication that removes the CSP header from /logon/LogonPoint/tmindex.html and adds a customized CSP for the DUO workflow. That example is useful, but it does not address every authentication integration. SAML integrations can involve additional NetScaler-generated responses, and an external IdP introduces another origin into the authentication flow, which is where the distinction between RESPONSE and AAA_RESPONSE becomes critical.
The Solution
The tested working solution is to remove the CSP header from the doSaml response using a targeted rewrite policy bound to the VPN vServer with -type AAA_RESPONSE.
Step 1: Create the Rewrite Action
// Create the Rewrite Action add rewrite action delete_csp_imprivata delete_http_header Content-Security-Policy
This action removes the CSP response header entirely from the matched response.
Step 2: Create the Rewrite Policy
// Create the Rewrite Policy add rewrite policy pol_delete_csp_imprivata "HTTP.REQ.URL.CONTAINS(\"/nf/auth/doSaml\")" delete_csp_imprivata
The policy limits the action to requests containing /nf/auth/doSaml, which is preferable to removing CSP from every Gateway response.
Step 3: Bind the Policy to the VPN Virtual Server
// Bind to VPN Virtual Server bind vpn vserver <YourGatewayVserver> -policy pol_delete_csp_imprivata -priority 100 -gotoPriorityExpression END -type AAA_RESPONSE
The critical parameter here is -type AAA_RESPONSE. Citrix specifically documents AAA_RESPONSE for Gateway responses generated by the packet engine. Binding with -type RESPONSE will not intercept this response in this topology.
Step 4: Save the Configuration
// Save Configuration save ns config
Verification
After applying the rewrite policy, you must confirm it is receiving hits. Begin this with:
// Verify Policy Hits show rewrite policy pol_delete_csp_imprivata
Trigger a new authentication session and check both the NetScaler policy statistics and the browser Developer Tools.
In the browser Developer Tools, monitor the authentication sequence: it should contain the request to /nf/auth/doSaml?ctx=… followed by the POST to the Imprivata SAML endpoint, without the CSP violation error. If the violation disappears and the SAML transaction proceeds to Imprivata, the rewrite policy is working correctly. If the authentication flow remains blocked or the rewrite policy does not receive hits, the following checks can help identify where the configuration may need further attention.
Troubleshooting Checklist
If the policy is not receiving hits, work through the following checklist:
| Check | What to Verify |
|---|---|
| Confirm the URL | Verify the request actually contains /ns/auth/doSaml |
| Check the bind point | The policy must be bound to the correct VPN vServer. |
| Check the bind type | Use -type AAA_RESPONSE for packet-engine-generated responses. |
| Check policy statistics | Hit count should increase during a new authentication attempt. |
| Inspect the actual response | Use browser Developer Tools to confirm which response contains the CSP header. |
| Check for caching | Run: flush cache contentgroup loginstaticobjects |
Key Findings
The findings below summarize the key components of the affected SAML authentication workflow, the CSP directive responsible for blocking the request, and the rewrite policy configuration validated during troubleshooting.
| Item | Finding |
|---|---|
| Affected workflow | NetScaler SAML authentication |
| Affected endpoint | /nf/auth/doSaml?ctx=… |
| External IdP | Imprivata Web SSO |
| SAML IdP endpoint | https://idp.cloud.imprivata.com/<tenant>/saml2/sso/post |
| SAML binding | HTTP POST |
| Relevant CSP directive | form-action ‘self’ |
| Response type | NetScaler Gateway/AAA-generated response |
| Required rewrite bind type | AAA_RESPONSE |
| Correct virtual server | VPN virtual server |
| Policy expression | HTTP.REQ.URL.CONTAINS(“/nf/auth/doSaml”) |
| RESPONSE bind tested | Yes |
| RESPONSE bind result | No hits in this troubleshooting scenario |
| Working bind | AAA_RESPONSE |
While the targeted rewrite policy resolves the authentication issue, removing the CSP header introduces security considerations that organizations should evaluate before implementing the change.
Security Considerations
Removing the CSP header from a specific authentication response is a narrower change than disabling the default CSP feature globally; however, it is still a security exception.
A better way to look at it is scope: the rewrite policy above is specifically limited to /nf/auth/doSaml rather than disabling CSP across the entire NetScaler Gateway, which limits the scope of the exception, but organizations should still evaluate the change against their security and compliance requirements.
Organizations with strict security requirements should evaluate this trade-off. The rewrite policy is intentionally scoped to /nf/auth/doSaml only, limiting the exception to the minimum required for the SAML flow to function.
Environment
The following table outlines the NetScaler Gateway and Imprivata Web SSO environment used to test and validate the rewrite policy configuration.
| Component | Version / Configuration |
|---|---|
| NetScaler ADC / Gateway | 14.1 |
| Default CSP behavior | Enabled by default starting with 14.1-47.46 |
| Identity Provider | Imprivata Web SSO |
| SAML architecture | NetScaler as SP, Imprivata as IdP |
| SAML binding | HTTP POST |
With the environment and configuration established, the key takeaway is the importance of identifying the response responsible for the CSP conflict and applying the rewrite at the correct bind point.
Lessons Learned
The important lesson from this issue is that a SAML authentication failure is not always a SAML configuration issue. In this case, the SAML configuration can be correct, the Imprivata endpoint can be reachable, and NetScaler can generate the expected SAML request, yet the browser can still stop the authentication flow because of CSP.
The key is identifying which response contains the restrictive CSP header and applying the rewrite at the correct response bind point. For NetScaler Gateway responses generated by the packet engine, that means paying particular attention to AAA_RESPONSE.
Once that distinction is understood, the troubleshooting becomes much more straightforward. Instead of disabling CSP globally, a targeted rewrite addresses the specific authentication response causing the issue.
References
- NetScaler: Content Security Policy response header support: https://docs.netscaler.com/en-us/citrix-adc/current-release/aaa-tm/aaa-rewrite/csp-header.html
- NetScaler: Rewrite for Gateway and authentication server-generated responses https://docs.netscaler.com/en-us/citrix-adc/current-release/aaa-tm/aaa-rewrite.html
- Imprivata: NetScaler Web SSO Setup with SAML 2.0 https://docs.imprivata.com/onesign/253/content/topics/onesign/sso/saml_netscaler.html
- Imprivata: Web SSO SAML 2.0 overview https://docs.imprivata.com/confirmid/253/content/topics/onesign/sso/saml_.html




