I had the same issue, and finally found a fix for it. Hopefully this will help anyone else that has the same problem.
Basically, you need to extend the RequestValidator base class that's part of System.Web.Util. Here's my class that will filter out both the unicode values and the actual full width less than and greater than symbols:
using System.Web;
using System.Web.Util;
namespace Common.Extensions
{
public class RequestValidatorExtension : RequestValidator
{
private const string UNICODE_LESS_THAN = "%uff1c";
private const string UNICODE_GREATER_THAN = "%uff1e";
public RequestValidatorExtension() { }
protected override bool IsValidRequestString(
HttpContext context,
string value,
RequestValidationSource requestValidationSource,
string collectionKey,
out int validationFailureIndex
)
{
validationFailureIndex = -1;
if (value.Contains(UNICODE_LESS_THAN))
value = value.ReplaceWith(UNICODE_LESS_THAN, "<");
else if (value.Contains("<"))
value = value.ReplaceWith("<", "<");
if (value.Contains(UNICODE_GREATER_THAN))
value = value.ReplaceWith(UNICODE_GREATER_THAN, ">");
else if (value.Contains(">"))
value = value.ReplaceWith(">", ">");
return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
}
}
}
In my case, when the "malicious" code was added into a text box, it would be passed in as the unicode value. However, when the query string was intercepted by Fiddler and modified, the value would be in the full width symbol. That is why there's a check for both.
You also have to register this new RequestValidationType in the web.config or in your global.asax page. Here's an example of both:
// Web.config
<httpRuntime requestValidationMode="2.0" requestValidationType="namespace.class" />
// Global.asax.cs
protected void Application_Start(object sender, EventArgs e)
{
RequestValidator.Current = new RequestValidatorExtension();
}
Also, here's a link to the MS documentation on how to utilize and extend the class.
Hope this helps, cheers!