Don’t trust a string based on TryParse or IsNumeric result! (.Net/VBScript)

According to MSDN, “IsNumeric returns a Boolean value indicating whether an expression can be evaluated as a number”, and (Numerical Datatype).TryParse converts the string representation of a number to its relevant numerical equivalent. A return Boolean value indicates whether the conversion succeeded or failed.

I have seen several cases where the developers were using TryParse or isNumeric only for validation, and they were not using a numeric variable at all; however, this could still cause functional and/or security issues in certain cases.

What is wrong with TryParse or IsNumeric then?!

There is nothing wrong with these functions if they are used correctly. In fact, these functions should not be used for validation only; they tell us if we can convert a string to its numerical format, and therefore, we can use a proper numerical variable instead of the string.

However, (numerical Datatype).TryParse is more useful than IsNumeric and can create the numerical equivalent as an output which can be used safely afterwards; it can also accept the permitted format(s) and the required culture format.

When can it go wrong?

From TryParse or IsNumeric point of view, a string can still be numeric even if it has some control characters or it follows a specific format as it can still be converted to a number. Therefore, the original string can be completely different in length and format from its equivalent numeric value. Now, if you use the original string when the results of these functions are true, we may have issues based on the destination system that uses them and trusts your validation. In real examples, I have seen a denial of service because of having a Null character in a serialized XML in the memory, or a denial of service because of sending a long string to a C++ component which did not have any validation and trusted the provided data.

The following table shows several test cases that can be combined as well (I have used URLEncoded values for the space and control characters):

String IsNumeric? Double.TryParse? Converted Number Comment(s)
001.0000 True True 1 decimal symbol based on the regional settings of the server
$10 True False 10 Currency symbol based on the regional settings of the server.
1,,2,,,3,, True True 123 Digit grouping symbol based on the regional settings of the server. Can be created by HPP too.
-10.0 True True -10 Negative symbol based on the regional settings of the server. It could be a positive sign.
(10) True False -10 Negative symbol based on the regional settings of the server.
10- True False -10 Negative symbol based on the regional settings of the server. It could be a positive sign.
1e2 True True 100 String length can be less than the number’s length
%20%091 True True 1 Space characters (09-0D and 20)
1%20%00%00 True True 1 Space characters (09-0D and 20) followed by Null Character(s)
%26hff True False 255 &h and &o can be used in VBScript to represent a number in Hex or Octal.
%0B%09%20-0001,,,,2.8e0002%09%20%0C%00%00 True True -1280 A combination
%0B$%09%20(0001,,,,2.8e0002%09%20)%0C%00%00 True False -1280 Another combination

You can try IsNumeric function by using the following link:

http://sdl.me/NumericTest/IsNumericTester.ashx?input=1

Source Code: http://sdl.me/NumericTest/IsNumericTester.ashx.vb.txt

You can try Double.TryParse function by using the following link:

http://sdl.me/NumericTest/DoubleTryParseTester.ashx?input=1

Source code: http://sdl.me/NumericTest/DoubleTryParseTester.ashx.cs.txt

Solution?

In .Net, (Numeric Data Type).TryParse automatically updates the relevant numeric variable for you that can be used later; it also accepts permitted format(s) and the required culture format of the input which is highly recommended to be used when you are looking for a specific format.

Example:

http://sdl.me/NumericTest/SafeDoubleTryParseTester.ashx?input=1

Source code: http://sdl.me/NumericTest/SafeDoubleTryParseTester.ashx.cs.txt

However, if you are a fan of using IsNumeric in VB, just make sure that you create a relevant numeric variable based on the input and convert the string to a number.

Another solution that may reduce the performance is validation by using a Regular Expression to check the numeric inputs in string. This method can be more useful if you are using different technologies (for example Java and .Net) at the same time to maintain consistency.

About Soroush Dalili
Web application security pentester.

One Response to Don’t trust a string based on TryParse or IsNumeric result! (.Net/VBScript)

  1. سعيد says:

    Also C# is a strongly typed language and you can’t assign a not numeric value to the
    int x;
    or else an exception will be thrown.