Roughing It: Security Rush

CodeThreat
6 min readSep 2, 2020

A journey of a software security request…

This is the story of a community triggered security request which was worked by the related project team and fixed by increasing the awareness through the sample code and the official documentation over a two-years period.

This is Bedirhan and in this post I’ll try to give you a pretty nice example of different phases and views of handling security concerns in real life. By the way I came across this example purely by chance and it was somehow exhilarating to dig the story further.

This is a relentlessly dug uncovered story of a security request

It All Starts with Curiosity

Here’s the starting point of the story. I was trying to write a file upload code example and was looking for alternatives. And the search led me to a blog post of a popular .NET Core package, elmah. It’s a well-known 3rd party package for easy logging;

https://blog.elmah.io/convert-images-to-webp-with-asp-net-core-better-than-png-jpg-files/

As I was reading the code, I saw the usage of property below in order to get access to the file name of the uploaded file.

Microsoft.AspNetCore.Http.IFormFile.FileName

But if you are suspicious developer, you get the feeling that using the user sent file name as is shouldn’t be secure. The blog writer himself probably has felt the same itchy feeling, so he put a rather futile validation before using it;

// Check if valid image type (can be extended with more rigorous checks)

string[] allowedImageTypes = new string[] { "image/jpeg", "image/png" };
if (!allowedImageTypes.Contains(image.ContentType.ToLower()))
return View();

The code above checks the content type of the uploaded file against a list of valid file types; png and jpeg. The problem is that the ContentType itself comes from the client side and open to modification. For example, an attacker can easily change the Content-Type value to png, but send an exe file to bypass the code check above.

Anyways, that’s one huge security problem, however, what I was curious was that something else. It was whether .NET Core’s IFormFile.FileName automatically normalizes the file name value that the user sends or not. Normalization is defined as the simplest form of something. In our case, if a user somehow sends for example

../photos/../../myphoto.png 

as the file name, normalization should automatically convert it to

myphoto.png

so that a malicious attempt is not possible. Well, was that the default case with IFormFile.FileName? Using the keywords below for a Google search should point me to the right direction.

IFormFile.FileName Directory Traversal

Here’s the search output. I was instantly amused by the second result.

Searching for any pointers to Directory Traversal attack against IFormFile.FileName .NET Core API

A Security Request Directed to .NET Core Team

Clicking on the link directs to a question asked to .NET Core developers about the same suspicion. Here’s the screenshot of it.

A user already asked about Directory Traversal attacks against IFormFile directly to .NET Core devs.

So, it all starts by a developer request about any protection mechanism around IFormFile.FileName. That’s the power of the open community.

The comments of this request are enlightening. For example, they are reluctant to include any proactive prevention technique into the API itself because of backward compatibility which is a pretty valid claim.

Any proactive prevention technique may create compatibility issues.

What they decided to do upon this request is to update the documentation including a clear guidance on the security repercussions of using IFormFile. As a result they enriched the documentation writing that;

Don't rely on or trust the `FileName` property without validation

Show Me The Code

So far so good. A year later, tough another request came up, requesting this time a proper way of validating a user sent file name value;

Another security related request form IFormFile.FileName

Upon this, a new issue was opened by the .NET Core team in May 2018 (and closed in January 2019) in order to add some security related validation code examples to the tutorial itself. The comments section of this issue is also valuable to see the understanding of developers and their design choices who have to fix an issue. For example, they don’t want to include too much security code blocks in the sample code they provide.

Thinking that it will create a false sense of security among developers who copy-paste this sample code. Since this is not a full solution I agree with them. However, they didn’t refrain from putting important validation code, such as not trusting to the file name that user sends but generating their own. Moreover, when using the file name user sends they HTML encode it in order to prevent injection attacks such as XSS.

Here’s a sample code block from the file upload tutorial of .NET Core that shows the two items I just mentioned above;

A security aware code block from file upload tutorial on .NET Core

And here’s the kick-ass File Upload .NET Core tutorial provided by the Microsoft documentation. It starts with Security considerations. This way copy-paste developers, including me, can directly benefit from the documentation itself when reading about file upload through .NET Core.

Microsoft .NET Core File Upload documentation starts with security considerations. How cool is that.

Before I go into my takeaways from these security requests, all and all, I really liked the way these guys handle a security problem initiated the developers themselves. Of course, team initiated effort could have also been possible, but, alas, who has the time, right?

Takeaways

  • Every framework or API designed for development purposes should have security considerations part written by the same team. It’s a huge requirement, so let me put a minimum scope. Every framework or API that may accept untrusted input should have a security consideration in their documentation. I really like to refer these parts to developers when they are in need.
  • Copy-paste programming is a fact. As a sample code producer we have to be aware of this and provide minimum but effective amount of validation built-in into the tutorial code projects.
  • Effective validation strategy means choosing whitelisting over blacklisting. Every analyst and developer should be aware of this. Moreover, whitelisting is not always the solution. We also have to use encoding whenever necessary. I’ll probably write about this concept more later on, in this blog.
  • Secure by default is so important. It could have been wiser to apply normalization on IFormFile.FileName by default starting from the earlier .NET era. That way there wouldn’t be any backward compatibility concerns. Instead, a wide range of Directory Traversal attacks would have been thwarted by default.
  • It’s critically important for developers to read the documentation of the APIs they are using. With a bit of critical approach, they would be able to find all the details required to secure their applications against hackers between the lines.

--

--

CodeThreat

CodeThreat is a static application security testing (SAST) solution. Visit codethreat.com