Click here to Skip to main content
15,941,828 members
Articles / .NET

Integer Overflow Vulnerabilities in .NET

Rate me:
Please Sign up or sign in to vote.
3.00/5 (1 vote)
8 Apr 2024CPOL3 min read 2.1K   2   2
Integer overflow vulnerabilities in .NET and other strongly typed applications

G’day guys!

Continuing with our exploration of various security vulnerabilities from a software developer’s perspective, I thought we could switch gears for a minute and look at something that affects (or has the potential to affect) .NET and other strongly typed applications.

Picking on .NET now, are we?

Image 1

Not specifically - likely any strongly typed language would be susceptible to this, and since we focused on PHP in the last article, it’s only fair to mix it up.

Alright already, show us the vulnerability

Imagine a code block that looks something like this:

C#
int a = 257;
byte b = (byte)a;

What do you think the value of b will be? Spoiler alert: it’s actually 1. As we know, a byte has 8 bits, and holds a range from 0 to 255. With 255, all 8 bits will be turned on, so it’s binary representation will look like 1111 1111. For a value of 257 though, it’d look like 1 0000 0001. Since the byte only holds 8 bits, the leading 1 will get stripped off, leaving just the trailing 1, so we end up with a value of 1 instead of 257.

Duh. How is that a vulnerability, though?

Well, imagine that you were doing something similar to this in your application, and that an attacker was able to manipulate the value of a. a here could represent a Price Id, Invoice Id, User Id or any other entity. By forcing the integer overflow to produce the value 1, the attacker could set the entity id to 1, which is likely the first record added to the system in databases that use auto-incrementing IDs. Some possible results might be that they could end up with elevated priveleges or free products.

Okay, that makes sense. But surely libraries and frameworks already handle this?

Somewhat. I did actually stumble upon this in practice back in .NET Framework land many years ago, but from my quick tests earlier, it looks like model binding in .NET Core has improved. These were what I noticed:

Library Overflow effect
.NET Core MVC Resets to zero
.NET Core Web Api Deserialization error
Newtonsoft.Json Deserialization error
System.Text.Json Deserialization error
CsvHelper Deserialization error

As you can see, it looks like most packages and frameworks will raise an error (or just default to zero) when an overflow is about to take place. Having said that, it’s probably still best not to rely on this and of course you’re not protected when doing any manual mapping or manual deserialization.

Fair enough! So how do we prevent it?

There are 3 approaches you could employ.

1. Manually check that the value is in range before copying it.

Coming back to our earlier example:

C#
int a = 257;
byte b = (byte)a;

One thing we could do is to verify that a is within the range of a byte before performing the assignment to b. For example:

C#
if (a < byte.MinValue || a > byte.MaxValue)
{
    throw new OverflowException($"{nameof(a)} was outside the bounds of a byte.");
}

This is a bit clunky though, especially if we’d have to repeat this logic throughout multiple parts of the codebase. Onto option 2!

2. Use a checked block

Another thing we could do is to have the compiler perform these checks for us by wrapping overflow-sensitive logic in a checked block. For example:

C#
checked
{
    int a = 257;
    byte b = (byte)a;
}

Here, the runtime will produce an OverflowException for any overflows (or underflows) that occur within the checked block. You might be wondering though, if your codebase does this a lot, if there’s a way to make this the default for the entire project.

Image 2

3. Turn on CheckForOverflowUnderflow in the project settings

In your csproj file, add <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow> to enable overflow checks for the entire codebase. There is of course the question of will this hurt application performance. I haven’t tested this myself, but I imagine if your project happens to be performing a lot of overflow/underflow checks already anyway, then this could be a wortwhile option to consider.

And that’s it for this write-up. Thanks for reading, and see you all next time.

Catch ya!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Australia Australia
G'day guys! My name is Jason, and I'm a backend software engineer living in Sydney, Australia. I enjoy blogging, playing chess and travelling.

Comments and Discussions

 
GeneralBy design ? Pin
Daniele Rota Nodari8-Apr-24 2:27
Daniele Rota Nodari8-Apr-24 2:27 
GeneralRe: By design ? Pin
Jason Sultana8-Apr-24 21:54
Jason Sultana8-Apr-24 21:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.