Form-fields are a major gate to send malicious data to a web-server.
It’s obvious, a website programmer does not want to do input validation twice, on the user and on the server-side. What could happen? If everything is tested on the client-side, data arriving on the server-side has to be good. Even worse: If an input field does not permit more than, let’s say, 60 characters, how could there be more?
It is extremely easy to change data on it’s way from the client to the server. There are plenty of ways to do so. One of these tools is Fiddler, an easy to use proxy. As all requests go via Fiddler, fiddler may edit the content and send it to the web-server. And who knows if all requests come from a browser?
So client-side input validation is not sufficient.
Unfortunately, it’s hardly possible to check, if an application itself validates all input fields before processing data. So, this job has to be done by Citrix ADC.
To me, the term Field Formats is a little bit misleading. It’s not just about field-formats, but also about HTML-parameters. From the perspective of a Citrix ADC / NetScaler WAF, there is no difference between a field, being passed via HTTP get, and a parameter. Parameters are another prominent backdoor, so I am totally fine with this.
A test environment
There are two sections:
Parameters transferred via HTTP get
Al links in this section open the same PHP file. They pass a parameter “colour” to select the right image. Possible values are 1, 2 and 3.
There are three dialogues (actually, it’s just one dialogue, but it uses different methods. Currently, we are just interested in the first two of them. The first one is using
<form action="/form-get.php" method="get">, so it is an HTML get, the other one
<form action="/form-post.php" method="post">, is an HTML post.
Parameters transferred via HTTP get
I created a firewall profile and policy, bound it to my load-balancing vServer, turned on learning for Field Formats and surfed to two of these documents.
The outcome of learning is:
So I could either click Deploy with Field Type, which would allow a single character integer, Deploy with Character Map or Edit & Deploy.
In this case, I would select Edit & Deploy and deploy it, using a character map containing 1, 2 and 3 (it’s a regex:
The rule will look like that:
add appfw fieldType CM1609170256374 "^[1-3]*$" 10000
bind appfw profile APPFW_prof_red -fieldFormat colour "^http://192\\.168\\.229\\.100/content\\.php$" CM1609170256374 -fieldFormatMaxLength 2 -comment "Deployed from learned data"
(a field type called CM1609170256374had been created. A rule defining the variable colour with this field type got bound to my profile).
From now on, every call to content.php needs to have either a parameter colour with values between 1 and 3, an empty value or none.
Forms with action “get”
Well, it’s more or less the same as the previous section.
Again, I turned on learning and learned several form fields:
There are several pre-defined field-types:
- integer (
(^[+-]?[0-9]+$) meaning: numbers, Possibly signed, at least one.
- alpha (
^[a-zA-Z0-0]+$) meaning: just letters, case-insensitive, at least one.
- alphanum (
^[a-zA-Z]+$) meaning: Letters (case-insensitive) or numbers, at least one.
- nonhtml (
^[^&<>]*$) meaning: any character except of &, < and >. 0 or more.
- any (
^(?s).*$) meaning: any characters as long as they are in a single line.
You could create your own field-types. For instance, I would need a field type “e-mail”. An e-mail address is in the form local-part “@” domain (see RFC 5322). There is RegEx following RFC 2822, unfortunately, it is way too long cor Citrix ADC / NetScaler. I don’t care about things like more than one period at the end of a mail address. So my RegEx would be something like that:
that means: the name may contain any character or number, as well as periods, dashers and underlines. There has to be at least one character, but no more than 100. Next, we need an at sign. The domain allows for characters, numbers, dots and dashers, again at least one, a maximum of 100. There has to be a period and a TLD. The TLD contain just characters, there is no TLD with less than 2 characters, and more than 20.
While this RegEx may not be a perfect solution, it works fine for 99,99% of all mail addresses.
Are RegEx, describing the values expected. They may be as complex as needed, but like always: Keep it simple!
No matter, if Character Map or Field Type: the length of parameters, passed to your application, might be a very critic parameter in Field Format definitions. It’s not just about malicious data, it’s also about oversized or undersized strings!
While the total length of parameters in Citrix ADC 13.0 and later is limited by the Query Length parameter in Buffer Overlow check, it absolutely makes sense to set rules about the of every form-fields.
Learning gives you an idea about the minimum and maximum length seen so far, however, it has no idea about the values your application expects. Choose the length wisely!
I hope, this was of some help to you. Like always, I would be happy to get your feedback and comments.