XSS, Signatures, Patterns & RFC URLs

Security Models & Signatures

The NetScaler WAF provides both positive and negative security models as possible protection configuration. The negative security model employs vulnerability signatures to prevent any known attacks.

This security model allows for rapid deployment of WAF. There is an extensive default set of signatures, but could be also based on external vulnerability scanners or you can create manually such.

This could be as easy as checking a box for all CVEs released in 2022/2023:


XSS & Application Responsibilities

Recently an external vulnerability scanner reported an XSS (Cross-site-scripting) expliot on an application proxied and protected by Citrix WAF. The application had only the negative security model applied. At first we were quite surprised as the XSS protection was turned on, but nothing was detected.

After thorough investigation it appeared the application was using unsafe characters in its URLs like " < >.

Due to the poorly written nature of the application's URL handling, the NetScaler was not able to properly detect the attack.

Per RFC 3986 - The specifications for Uniform Resource Identifiers (URIs) and more specifically Uniform Resource Locators (URLs) provide a safe, consistent way to request, identify, and resolve resources on the Internet. Developers and applications failing to do so introduces potential security vulnerabilities which may be exploited by malicious scripts and threat actors. Not only that but certian characters should be URL Encoded for same exact reason.

Quick reference explaining which characters are “safe” and which characters should be encoded in URLs:

Character Table

ClassificationIncluded charactersEncoding required?
Safe charactersAlphanumerics [0-9a-zA-Z] and unreserved characters. Also reserved characters when used for their reserved purposes (e.g., question mark used to denote a query string)NO
Unreserved characters- . _ ~ (does not include blank space)NO
Reserved characters: / ? # [ ] @ ! $ & ' ( ) * + , ; = (does not include blank space)YES
Unsafe charactersIncludes the blank/empty space and ` " % | \ ^ { } < >YES
ASCII Control charactersIncludes the ISO-8859-1 (ISO-Latin) character ranges 00-1F hex (0-31 decimal) and 7F (127 decimal)YES
Non-ASCII charactersIncludes the entire “top half” of the ISO-Latin set 80-FF hex (128-255 decimal)YES
All other charactersAny character(s) not mentioned above should be percent-encoded.YES

WAF Detection Mechanisms

XSS is type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. Security scanners have a common practice of using alert() function for detection purposes because it's short, harmless, and pretty hard to miss when it's successfully called. The XSS config model on the NetScaler is hybrid, meaning it could be based entirely on patterns (negative security model), but it could utilize learning as well (positive security model).

The XSS pattern detection (negative security model) consists of the following components:

  • xss/allowed/attribute
  • xss/allowed/tag
  • xss/denied/pattern

These are located in your signature config under Manage CMD/SQL/XSS patterns:


The Tags, Attributes, and Patterns, specified in the signatures object will be used for XSS detection. It will block tags not whitelisted and the denied patterns. If you do not bind any signature object to your profile, the default cross-site scripting Allowed and Denied list specified in the Default Signatures object will be used by the profile for the Cross-Site Scripting security check processing.

As such application handling unsafe characters could introduce loopholes in the security detection mechanisms.

We'll need to create a custom block action and you can do this by several different ways:

  • Custom signatures
  • Deny URL
  • XSS Deny Patterns

If the XSS isn't parsed via the URL, then you are left with the first choice. Have in mind that XSS supports custom Deny Patterns, but in my case it would not be detected as no tags are parsed.


There is no way of configuring new signature objects through CLI. For the moment new signatures can be created only through the GUI.

You can enable or disable existing signatures via the below commands.

First you'll need to list your signature object and note your signature URL and Name.

show appfw signatures APPFW_SIGN_ALEKAF

Next substitute the URL, Name, signature ID and action in the below CLI.

If you wish to enable Rule 998722:

import appfw signatures local:_sig_1686137326413 APPFW_SIGN_ALEKAF -ruleId 998722 -Enabled ON -Action LOG BLOCK
update appfw signatures APPFW_SIGN_ALEKAF

Signatures are stored in xml format at directory /var/tmp/. You can import via GUI or CLI new set of signatures via below commands:

Upload Custom Signature File to directory:  /var/tmp/ 
import appfw signatures local:<custom_sign_file>.xml <SIGNATURE_NAME> -autoEnableNewSignatures OFF -comment "13.1 06.04.23 Import" 
update appfw signatures <SIGNATURE_NAME>
show appfw <SIGNATURE_NAME>

Creating Custom Signatures

First option is to create a custom signature detecting the XSS exploit in question.

Edit the signature object and add new object. I would create a custom category (called web-custom) where my custom\external signatures to be stored.


Give the signature an ID and LogString identification:


Next create signatures rule pattern.

You always need to have at least one literal detection pattern in your signature rules. This could be targeting specific URL, Header.

Targeting every URL could be configured by matching "/". Enable fastmatch on it. After that you can add your PCRE detection of the violation. In my opinion the requirement for at least one literal match (with fastmatch) is to reduce processing overhead and optimize performance while evaluating the signatures. The more accurate your signature is the faster will be processed.


The request must match (evaluate to true) to both literal and PCRE expressions!

I'll create same for detecting violations in headers. The result is two custom signatures in web-custom category.


Deny URL

Second option is to create a Deny URL detection of unsafe characters. If you know your application architecture you can include even some of the reserved characters.

Enable Deny URL block feature and configure Deny Rule:

set appfw profile APPFW_PROF_ALEKAF -denyURLAction block log stats
bind appfw profile APPFW_PROF_ALEKAF -denyURL q/(\\|\^|{|}|`|<|>|%|"|'|\|)/ -comment "RFC 3986 - Block Unsafe Characters" -resourceId 51e2e74c0bfccbabea50dddd9a9fec081e041714a9c2e7425142f3b27898056s

You can revert with the below command:

unbind appfw profile APPFW_PROF_ALEKAF -denyURL q/(\\|\^|{|}|`|<|>|%|"|'|\|)/

This concludes Part 1.

Thank you for reading!