I’ve recently been playing around with all of the new features packaged into C# 7.2. One such feature that piqued my interest because of it’s simplicity was the “in” keyword. It’s one of those things that you can get away with never using in your day to day work, but makes complete sense when looking at language design from a high level.

In simple terms, the in  keyword specifies that you are passing a parameter by reference, but also that you will not modify the value inside a method. For example :

In this example we pass in two parameters essentially by reference, but we also specify that they will not be modified within the method. If we try and do something like the following :

We get a compile time error:

Accessing C# 7.2 Features

I think I should just quickly note how to actually access C# 7.2 features as they may not be immediately available on your machine. The first step is to ensure that Visual Studio is up to date on your machine. If you are able to compile C# 7.2 code, but intellisense is acting up and not recognizing new features, 99% of the time you just need to update Visual Studio.

Once updated, inside the csproj of your project, add in the following :

And you are done!


When passing value types into a method, normally this would be copied to a new memory location and you would have a clone of the value passed into a method. When using the in  keyword, you will be passing the same reference into a method instead of having to create a copy. While the performance benefit may be small in simple business applications, in a tight loop this could easily add up.

But just how much performance gain are we going to see? I could take some really smart people’s word for it, or I could do a little bit of benchmarking. I’m going to use BenchmarkDotNet (Guide here) to compare performance when passing a value type into a method normally, or as an in  parameter.

The benchmarking code is :

And the results :

We can definitely see the speed difference here. This makes sense because really all we are doing is passing in a variable and doing nothing else. It has to be said that I can’t see the in  keyword being used to optimize code in everyday business applications, but there is definitely something there for time critical applications such as large scale number crunchers.

Explicit In Design

While the performance benefits are OK something else that comes to mind is that when you use in  is that you are being explicit in your design. By that I mean that you are laying out exactly how you intend the application to function. “If I pass this a variable into this method, I don’t expect the variable to change”. I can see this being a bigger benefit to large business applications than any small performance gain.

A way to look at it is how we use things like private  and readonly . Our code will generally work if we just make everything public  and move on, but it’s not seen as “good” programming habits. We use things like readonly  to explicitly say how we expect things to run (We don’t expect this variable to be modified outside of the constructor etc). And I can definitely see in  being used in a similar sort of way.

Comparisons To “ref” (and “out”)

A comparison could be made to the ref keyword in C# (And possibly to a lesser extend the out keyword). The main differences are :

in  – Passes a variable in to a method by reference. Cannot be set inside the method.
ref  – Passes a variable into a method by reference. Can be set/changed inside the method.
out  – Only used for output from a method. Can (and must) be set inside the method.

So it certainly looks like the ref keyword is almost the same as in, except that it allows a variable to change it’s value. But to check that, let’s run our performance test from earlier but instead add in a ref scenario.

So it’s close when it comes to performance benchmarking. However again, in  is still more explicit than ref because it tells the developer that while it’s allowing a variable to be passed in by reference, it’s not going to change the value at all.

Important Performance Notes For In

While writing the performance tests for this post, I kept running into instances where using in  gave absolutely no performance benefit whatsoever compared to passing by value. I was pulling my hair out trying to understand exactly what was going on.

It wasn’t until I took a step back and thought about how in  could work under the hood, coupled with a stackoverflow question or two later that I had the nut cracked. Consider the following code :

What will the output be? If you guessed 1. You would be correct! So what’s going on here? We definitely told our struct to set it’s value to 1, then we passed it by reference via the in keyword to another method, and that told the struct to update it’s value to 5. And everything compiled and ran happily so we should be good right? We should see the output as 5 surely?

The problem is, C# has no way of knowing when it calls a method (or a getter) on a struct whether that will also modify the values/state of it. What it instead does is create what’s called a “defensive copy”. When you run a method/getter on a struct, it creates a clone of the struct that was passed in and runs the method instead on the clone. This means that the original copy stays exactly the same as it was passed in, and the caller can still count on the value it passed in not being modified.

Now where this creates a bit of a jam is that if we are cloning the struct (Even as a defensive copy), then the performance gain is lost. We still get the design time niceness of knowing that what we pass in won’t be modified, but at the end of the day we may aswell passed in by value when it comes to performance. You’ll see in my tests, I used plain old variables to avoid this issue. If you are not using structs at all and instead using plain value types, you avoid this issue altogether.

To me I think this could crop up in the future as a bit of a problem. A method may inadvertently run a method that modifies the structs state, and now it’s running off “different” data than what the caller is expecting. I also question how this will work in multi-threaded scenarios. What if the caller goes away and modified the struct, expecting the method to get the updated value, but it’s created a defensive clone? Plenty to ponder (And code out to test in the future).


So will there be a huge awakening of using the in keyword in C#? I’m not sure. When Expression-bodied Members (EBD) came along I didn’t think too much of them but they are used in almost every piece of C# code these days. But unlike EBD, the in  keyword doesn’t save typing or having to type cruft, so it could just be resigned to one of those “best practices” lists. Most of all I’m interested in how in  transforms over future versions of C# (Because I really think it has to).   What do you think?

This article is part of a series on setting up a private nuget server. See below for links to other articles in the series.

Part 1 : Intro & Server Setup
Part 2 : Developing Nuget Packages
Part 3 : Building & Pushing Packages To Your Nuget Feed

In our previous article in this series, we looked at how we might go about setting up a nuget server. With that all done and dusted, it’s on to actually creating the libraries ourselves. Through trial and error and a bit of playing around, this article will dive into how best to go about developing the packages themselves. It will include how we version packages, how we go about limiting dependencies, and in general a few best practices to play with.

Use .NET Standard

An obvious place to begin is what framework to target. In nearly all circumstances, you are going to want to target .NET Standard (See here to know what .NET Standard actually is). This will allow you to target .NET Core, Full Framework and other smaller runtimes like UWP or Mono.

The only exception to the rule is going to come when you are building something especially specific for those runtimes. For example a windows form library that will have to target full framework.

Limit Dependencies

Your libraries should be built in such a way that someone consuming the library can use as little or as much as they want. Often this shows up when you add in dependencies to your library that only a select people need to use. Remember that regardless of whether someone uses that feature or not, they will need to drag that dependency along with them (And it may also cause versioning issues on top of that).

Let’s look at a real world example. Let’s say I’m building a logging library. Somewhere along the way I think that it would be handy to tie everything up using Autofac dependency injection as that’s what I mostly use in my projects. The question becomes, do I add Autofac to the main library? If I do this, anyone who wants to use my library needs to either also use Autofac, or just have a dependency against it even though they don’t use the feature. Annoying!

The solution is to create a second project within the solution that holds all our Autofac code and generate a secondary package from this project. It would end up looking something like this :

Doing this means that anyone who wants to also use Autofac can reference the secondary package (Which also has a dependency on the core package), and anyone who wants to roll their own dependency injection (Or none at all) doesn’t need to reference it at all.

I used to think it was annoying when you searched for a nuget package and found all these tiny granular packages. It did look confusing. But any trip to DLL Hell will make you thankful that you can pick and choose what you reference.

Semantic Versioning

It’s worth noting that while many Microsoft products use a 4 point versioning system (<major>.<minor>.<build>.<revision>), Nuget packages work off whats called “Semantic Versioning” or SemVer for short. It’s a 3 point versioning system that looks like <major>.<minor>.<patch>. And it’s actually really simple and makes sense when you look at how version points are incremented.

<major> is updated when a new feature is released that breaks backwards compatibility. For example if someone upgrades from version 1.2.0 to 2.0.0, they will know that their code very likely will have to change to accommodate the upgrade.

<minor> is updated when a new feature is released that is backwards compatible. A user upgrade a minor version should not have to touch their existing code for things to continue working as per normal.

<patch> is updated for bug fixes. Bug fixes should always be backwards compatible. If they aren’t able to be, then you will be required to update the major version number instead.

We’ll take a look at how we set this in the next section, but it’s also important to point out that there will essentially be 3 version numbers to set. I found it’s easier to just set them all to exactly the same value unless there is a really specific reason to not do so. This means that for things like the “Assembly Version” where it uses the Microsoft 4 point system, the last point is always just zero.

Package Information

In Visual Studio if you right click on a project and select properties, then select “Package” on the left hand menu. You will be given a list of properties that your package will take on. These include versions, the company name, authors and descriptions.

You can set them here, but they actually then get written to the csproj. I personally found it easier to edit the project file directly. It ends up looking a bit like this :

If you edit the csproj directly, then head back to Visual Studio properties pane to take a look, you’ll see that they have now been updated.

The most important thing here is going to be all the different versions seen here. Again, it’s best if these all match with “Version” being a SemVer with 3 points of versioning.

For a full list of what can be set here, check the official MS Documentation for csproj here.

Shared Package Information/Version Bumping

If we use the example solution above in the section for “Limit Dependencies” where we have multiple projects that we want to publish nuget packages for. Then we will likely want to be able to share various metadata like Company, Copyright etc among all projects from a single source file rather than having to update each one by one. This might extend to version bumping too, where for simplicity sake when we release a new version of any package in our solution, we want to bump the version of everything.

My initial thought was to use a linked “AssemblyInfo.cs” file. It’s where you see things like this :

Look familar? The only issue was that there seemed to be quite a few properties that couldn’t be set using this, for example the “Author” metadata. And secondly when publishing a .NET Standard nuget package, it seemed to completely ignore all “version” attributes in the AssemblyInfo.cs. Meaning that every package was labelled as version 1.0.0

By chance I had heard about a feature of “importing” shared csproj fields from an external file. And as it turned out, there was a way to place a file in the “root” directory of your solution, and have all csproj files automatically read from this.

The first step is to create a file called “Directory.Build.props” in the root of your solution. Note that the name actually is “Directory”, do not replace this for the actual directory name (For some stupid reason I thought this was the case).

Inside this file, add in the following :

And by magic, all projects underneath this directory will overwrite their metadata with the data from this file. Using this, we can bump versions or change the copyright notice of all child projects without having to go one by one. And ontop of that, it still allows us to put a description in each individual csproj too!


The hardest part about all of this was probably the shared assembly info and package information. It took me quite a bit of trial and error with the AssemblyInfo.cs file to work out it wasn’t going to happen, and surprisingly there was very little documentation about using a .props file to solve the issue.

The final article in the series will look into how we package and publish to our nuget feed. Check it out here!

This article is part of a series on the OWASP Top 10 for ASP.net Core. See below for links to other articles in the series.

A1 – SQL Injection A6 – Sensitive Data Exposure (Coming Soon)
A2 – Broken Authentication and Session Management A7 – Insufficient Attack Protection (Coming Soon)
A3 – Cross-Site Scripting (XSS) A8 – Cross-Site Request Forgery (Coming Soon)
A4 – Broken Access Control A9 – Using Components with Known Vulnerabilities (Coming Soon)
A5 – Security Misconfiguration (Coming Soon) A10 – Underprotected APIs (Coming Soon)

Broken Access Control is a new entry into the OWASP Top 10. In previous years there were concepts called “Insecure Direct Object References” and “Missing Function Level Access Controls” which have sort of been bundled all together with a couple more additions. This entry reminds me quite a bit of Broken Authentication because it’s very broad and isn’t that specific. It’s more like a mindset with examples given on things you should look out for rather than a very particular attack vector like SQL Injection. None the less, we’ll go through a couple of examples given to us by OWASP and see how they work inside .NET Core.

What Is Broken Access Control

Broken Access Control refers to the ability for an end user, whether through tampering of a URL, cookie, token, or contents of a page, to essentially access data that they shouldn’t have access to. This may be a user being able to access somebody elses data, or worse, the ability for a regular user to elevate their permissions to an admin or super user.

The most common vulnerability that I’ve seen is code that verifies that a user is logged in, but not that they are allowed to access a particular piece of data. For example, given a URL like www.mysite.com/orders/orderid=900  what would happen if we changed that orderid by 1? What if a user tried to access  www.mysite.com/orders/orderid=901. There will likely be code to check that a user is logged in (Probably a simple Authorize attribute in .NET Core). But how about specific code to make sure that the order actually belongs to that particular customer? It’s issues like this that make up the bulk of the Broken Access Control.

Where I start to veer away from the official definition from OWASP is that the scope starts exploding after this. I think when you try and jam too much under a single security headline, it starts losing it’s meaning. SQL Injection for example is very focused and has very specific attack vectors. Access Control is much more broader subject. For example, the following is defined as “Broken Access Control” by OWASP :

  • Misconfigured or too broad CORS configuration
  • Web server directory listing/browsing
  • Backups/Source control (.git/.svn) files present in web roots
  • Rate limiting of APIs
  • JWT Tokens not being invalidated on logout

And the list goes on. Essentially if you ask yourself “Should a web user be able to access this data in this way”, and the answer is “no”, then that’s Broken Access Control in a nutshell.

Insecure Direct Object References

As we’ve already seen, this was probably the grandfather of Broken Access Control in the OWASP Top 10. Direct object references are id’s or reference variables that are able to be changed by an end user, and they can then retrieve records that they should not be privy to.

As an example, let’s say we have the following action in a controller :

Now this is authorized somewhat as seen by the authorize header. This means a completely anonymous user can’t hit this endpoint, but it doesn’t stop one logged in user accessing a different user’s orders. Any id passed into this endpoint will return an order object no questions asked.

Let’s modify it a bit.

This will require a bit of imagination, but hopefully not too much!

Imagine that when we log in our user, we also store their customerid in a claims. That means we forever have access to exactly who is logged in when they try and make requests, not just that they are loggedin in general. Next, on each Order we store the CustomerId of exactly who the order belongs to. Finally, it means that when someone tries to load an order, we get the Id of the customer logged in, and compare that to the CustomerId of the actual order. If they don’t match, we reject the request. Perfect!

An important thing to note is that URL’s aren’t the only place this can happen. I’ve seen hidden fields, cookies, and javascript variables all be susceptible to this kind of abuse. The rule should always be that if it’s in the browser, a user can modify it. Server side validation and authorization is king.

One final thing to mention when it comes to direct object references is that “Security through obscurity” is not a solution. Security through obscurity refers to a system being secure because of some “secret design” or hidden implementation being somewhat “unguessable” by an end user. In this example, if we change our initial get order method to :

So now our OrderId is a Guid. I’ve met many developers that think this is now secure. How can someone guess a Guid? It is not feasible to enumerate all guids against a web endpoint (If it was feasible than we would have many more clashes), and this much is true. But what  if someone did get a hold of that guid from a customer? I’ve seen things like a customer sending a screenshot of their browser to someone else, and their Order Guid being in plain sight. You can’t predict how this Guid might leak in the future, malicious or stupidness. That’s why again, server side authorization is always king.

CORS Misconfiguration

CORS refers to limiting what website can place javascript on their page to then call your API. We have a great tutorial on how to use CORS in ASP.net Core here. In terms of OWASP, the issue with CORS is that it’s all too easy to just open up your website to all requests and call it a day. For example, your configuration may look like the following :

Here you are just saying let anything through, I don’t really care. The security problem becomes extremely apparent if your API uses cookies as an authentication mechanism. A malicious website can make a users browser make Ajax calls to the API, the cookies will be sent along with the request, and sensitive data will be leaked. It’s that easy.

In simple terms, unless your API is meant to be accessed by the wider public (e.g. the data it is exposing is completely public), you should never just allow all origins.

In ASP.net Core, this means specifying which websites are allowed to make Ajax calls.

As with all security configurations, the minimum amount of access available is always the best setting.

Directory Traversal and Dangerous Files

I lump these together because they should be no-brainers, but should always be on your checklist when deploying a site for the first time. The official line in the OWASP handbook when it comes to these is :

Seems pretty simple right? And that’s because it is.

The first is that I’ve actually never had a reason to allow directory traversal on a website. That is, if I have a URL like www.mysite.com/images/image1.jpg , a user can’t simply go to www.mysite.com/images/ and view all images in that directory. It may seem harmless at first, like who cares if a user can see all the images on my website. But then again, why give a user the ability to enumerate through all files on your system? It makes no sense when you think about it.

The second part is that metadata type files, or development only files should not be available on a web server. Some are obviously downright dangerous (Site backups could leak passwords for databases or third party integrations), and other development files could be harmless. Again it makes zero sense to have these on a web server at all as a user will never have a need to access them, so don’t do it!


While I’ve given some particular examples in this post, Broken Access Control really boils down to one thing, If a user can access something they shouldn’t, then that’s broken access control. While OWASP hasn’t put out too much info on this subject yet, a good place to start is the official OWASP document for 2017 (Available here). Within .NET Core, there isn’t any “inherit” protection against this sort of thing, and it really comes down to always enforcing access control at a server level.

Next post we’ll be looking at a completely new entry to the OWASP Top 10 for 2017, XML External Entities (XXE).

Benchmarking your code can take on many forms. On some level Application Performance Monitoring (APM) solutions such as New Relic can sometimes be considered live benchmarking tools if you are using A/B testing. All the way down to wrapping a stopwatch object around your code and running it inside a loop. This article will be looking more towards the latter. Benchmarking specific lines of code either against each other or on it’s own to get performance metrics can be extremely important in understanding how your code will run at scale.

While wrapping your code in a timer and running it a few hundred times is a good start, it’s not exactly reliable. There are far too many pitfalls that you can get trapped in that completely skew your results. Luckily there is always a Nuget package to cover you! That package in this case is BenchmarkDotNet. It takes care of things like warming up your code, isolating each benchmark from each other, and giving you metrics on code performance. Let’s jump straight in!

Code Benchmarking

Code Benchmarking is when you want to compare two pieces of code/methods against each other. It’s a great way to quantify a code rewrite or refactor and it’s going to be the most common use case for BenchmarkDotNet.

To get started, create a blank .NET Core console application. Now, most of this “should” work when using .NET Full Framework too, but I’ll be doing everything here in .NET Core.

Next you need to run the following from your Package Manager console to install the BenchmarkDotNet nuget package :

Next we need to build up our code. For this we are going to use a classic “needle in a haystack”. We are going to build up a large list in C# with random items within it, and place a “needle” right in the middle of the list. Then we will compare how doing “SingleOrDefault” on a list compares to “FirstOrDefault”. Here is our complete code :

Walking through this a bit, first we create a class to hold our benchmarks within it. This can contain any number of private methods and can include setup code within the constructor. Any code within the constructor is not included in the timing of the method. We can then create public methods and add the attribute of  [Benchmark] to have them listed as items that should be compared and benchmarked.

Finally inside our main method of our console application, we use the “BenchmarkRunner” class to run our benchmark.

A word of note when running the benchmarking tool. It must be built in “Release” mode, and run from the command line. You should not use benchmarks run from Visual Studio as this also attaches a debugger and is not compiled as “optimized”. To run from the command line, head to your applications bin/Release/netcoreappxx/ folder, then run  dotnet {YourDLLName}.dll

And the results?

So it looks like Single is twice as slow as First! If you understand what Single does under the hood, this is to be expected. When First finds an item, it immediately returns (After all, it only wants the “First” item). However when Single finds an item, it still needs to traverse the entire rest of the list because if there is more than one, it needs to throw an exception. This makes sense when we are placing the item in the middle of the list!

Input Benchmarking

Let’s say that we’ve found Single is slower than First. And we have a theory on why that is (That Single needs to continue through the list), then we may need a way to try different “configurations” without having to re-run the test with minor details changed. For that we can use the “Input” feature of BenchmarkDotNet.

Let’s modify  our code a bit :

What we have done here is create a “_needles” property to hold different needles we may wish to find. And we’ve inserted them at different indexes within our list. We then create a “Needle” property with the attribute of ParamsSource”. This tells BenchmarkDotNet to rotate through these and run a different test for each possible value.

A big tip is that the ParamsSource must be public, and it must be a property – It cannot be a property.

Running this, our report now looks like so :

It’s a little harder to see because we are now down to nanoseconds based on the time that “First” takes to return the StartNeedle. But the results are very clear.

When Single is run, the time it takes to return the needle is the same regardless of where it is in the list. Whereas First’s response time is totally dependent on where the item is in the list.

The Input feature can be a huge help in understand how or why applications slow down given different inputs. For example does your password hashing function get slower when passwords are longer? Or is it not a factor at all?

Creating A Baseline

One last helpful tip that does nothing more than create a nice little “multiplier” on the report is to mark one of your benchmarks as the “baseline”. If we go back to our first example (Without Inputs), we just need to mark one of our Benchmarks as baseline like so :  [Benchmark(Baseline = true)]

Now when we run our test with “First” marked as the baseline, the output now looks like :

So now it’s easier to see the “factor” by which our other methods are slower (Or faster). In this case our Single call is almost twice as slow as the First call.

What Have You Benchmarked?

As programmers we love seeing how a tiny little change can improve performance by leaps and bounds. If you’ve used BenchmarkDotNet to benchmark a piece of code and you’ve been amazed by the results, drop a comment below with a Github Gist of the code and a little about the what/why/how it was slow!

JSONPatch is a method of updating documents on an API in a very explicit way. It’s essentially a contract to describe exactly how you want to modify a document (For example, replace the value in a field with another value) without having to also send along the rest of the unchanged values.

What Does A JSON Patch Request Look Like?

The official documentation for JSON Patch lives here : http://jsonpatch.com/, but we’ll do a bit of digging to see how it works inside ASP/C# as not all applications will work. Infact one operation has not yet made it into an official release of ASP.net Core, but we’ll do a quick talk about it anyway.

For all examples, I will be writing JSON Patch requests against an object that looks like so in C# :

Patch requests all follow a similar type of structure. It’s a list of “operations” within an array. The operation itself has 3 properties.

“op” – Defines the “type” of operation you want to do. For example add, replace, test etc.
“path” – The “path” of the property on the object you want to edit. In our example above, if we wanted to edit “FirstName” the “path” property would look like “/firstname”
“value” – For the most part, defines the value we want to use within our operation.

Now let’s look at each individual operation.


The Add Operation typically means that you are adding a property to an object or “adding” an item into an array. For the former, this does not work in C#. Because C# is a strongly typed language, you cannot “add” a property onto an object that wasn’t already defined at compile time.

To add an item into an array the request would look like the following :

This would “insert” the value of “Mike” at index 1 in the Friends array. Alternatively you can use the “-” character to insert a record at the end of the array.


Similar to the “Add” operation outlined above, the Remove Operation typically means you are either removing a property from an object or removing an item from an array. But because you can’t actually “remove” a property from an object in C#, what actually happens is that it will set the value to default(T). In some cases if the object is nullable (Or a reference type), it will be set to NULL. But be careful because when used on value types, for example an int, then the value actually gets reset to “0”.

To run Remove on an object property to “reset” it, you would run the following :

You can also run the Remove operation to remove a particular item in an array

This removes the item from array index 1. There is no such “where” clause for removing or deleting so at times this can seem pretty dangerous to just remove an item from an array index like this since what if the array has changed since we fetched it from the server? There is actually a JSON Patch operation that will help with this, but more on that later.


Replace does exactly what it says on the tin. It replaces any value for another one. This can work for simple properties on objects :

It can also replace particular properties inside an array item :

And it can also replace entire objects/arrays like so :


Copy will move a value from one path to another. This can be a property, object, array etc. In the example below we move the value of the Firstname to the LastName. In practical terms this doesn’t come up a whole lot because you would typically see a simple replace on both properties rather than a copy, but it is possible! If you actually dive into the source code of the ASP.net Core implementation of JSON Patch, you will see that a copy operation simple does an “Add” operation in the background on the path anyway.


The Move operation is very similar to a Copy, but as it says on the tin, the value will no longer be at the “from” field. This is another one that if you look under the hood of ASP.net Core, it actually does a remove on the from field, and an add on the Path field.


The Test operation does not currently exist in a public release of ASP.net Core, but if you check the source code up on Github, you can see that it’s already being worked on by Microsoft and should make it to the next release. Test is almost a way of doing optimistic locking, or in simpler terms a check to see if the object on the server has changed since we retrieved the data.

Consider the following full patch :

What this says is, first check that on the path of “/FirstName” that the value is Bob, and if it is, change it to Jim. If the value is not Bob, then nothing will happen. An important thing to note is that you can have more than one Test operation in a single patch payload, but if any one of those Tests fail, then the entire Patch will not be applied.

But Why JSON Patch Anyway?

Obviously a big advantage to JSON Patch is that it’s very lightweight in it’s payload, only sending exactly what’s changed on the object. But there is another big benefit in ASP.net Core, it actually has some great utility for the sole reason that C# is a typed language. It’s hard to explain without a good example. So imagine I request from an API a “Person” object. In C# the model may look like :

And when returned from an API as a JSON object, it looks like so :

Now from the front end, without using JSON Patch,  I decide that I only need to update the firstname so I send back the following payload :

Now a question for you when I deserialize this model in C#. Without looking below. What will the values of our model be?

Hmmm. So because we didn’t send through the LastName, it gets serialized to Null. But that’s easy right, we can just ignore values that are null and do something finicky on our data layer to only update the fields we actually passed through. But that’s not necessarily true, what if the field actually is nullable? What if we sent through the following payload :

So now we’ve actually specified that we want to null this field. But because C# is strongly typed, there is no way for us to determine on the server side that a value is missing from the payload vs when it’s actually been set to null with standard model binding.

This may seem like an odd scenario, because the front end can just always send the full model and never omit fields. And for the most part the model of a front end web library will always match that of the API. But there is one case where that isn’t always true, and that’s mobile applications. Often when submitting a mobile application to say the Apple App Store, it may take weeks to get approved. In this time, you may also have web or android applications that need to be rolled out to utilize new models. Getting synchronization between different platforms is extremely hard and often impossible. While API versioning does go a long way to taking care of this, I still feel JSON Patch has great utility in solving this issue in a slightly different way.

And finally, it’s to the point! Consider the following JSON Patch payload for our Person object :

This explicitly says that we want to change the first name and nothing else. There is never ambiguity of “did we just forget to send that property or do we actually want it ‘nulled out'”. It’s precise and tells us exactly what’s about to happen.

Adding JSON Patch To Your ASP.net Core Project

Inside Visual Studio, run the following from the Package Manager console to install the official JSON Patch library (It does not come with ASP.net Core in a new project out of the box).

For this example, I’ll use the following full controller. The main point to note is that the HTTP Verb we use is “Patch”, we accept a type of “JsonPatchDocument<T>” and that to “apply” the changes we simply call “ApplyTo” on the patch and pass in the object we want to update.

In our example we are just using a simple object stored on the controller and updating that, but in a real API we will be pulling the data from a datasource, applying the patch, then saving it back.

When we call this endpoint with the following payload :

We get the response of :

Awesome! Our first name got changed to Bob! It’s really that simple to get up and running with JSON Patch.

Generating Patches

The first question many people ask is exactly how should they be crafting their JSON Patch payloads. You do not have to do this manually! There are many javascript libraries that can “compare” two objects to generate a patch. And even easier, there are many that can “observe” an object and generate a patch on demand. The JSON Patch website has a great list of libraries to get started : http://jsonpatch.com/

Using Automapper With JSON Patch

The big question I often see around JSON Patch, is that often you are returning View Models/DTOs from your API, and generating patches from there. But then how do you apply those patches back onto a database object? People tend to overthink it and create crazy “transforms” to turn a patch from one object to another, but there is an easier way using Automapper that is extremely simple to get going. The code works like so :

An important thing to note is that when mapping the DTO back to the Database object in the second Map call, Automapper has a great function where it can map onto an existing object, and only map fields that it cares about. Any additional fields that are on the database object will be left alone.

If you need help setting up Automapper, check out our great tutorial on Using Automapper In ASP.net Core.

In previous posts I’ve talked about how you can now use the legacy SMTPClient class inside .NET to send emails. As commentators on this post have pointed out however, this has now been deprecated and the official documentation actually points you towards a very popular email library called “MailKit“. It’s open source, it’s super extensible, and it’s built on .NET Standard meaning that you can use the same code across .NET Full Framework, UWP and .NET Core projects.

Creating An Email Service

It’s always good practice that when you add in a new library, that you build an abstraction on top of it. If we take MailKit as an example, what if MailKit is later superceded by a better emailing library? Will we have to change references all over our code to reference this new library? Or maybe MailKit has to make a breaking change between versions, will we then have to go through our code fixing all the now broken changes?

Another added bonus to creating an abstraction is that it allows us to map out how we want our service to look before we worry about implementation details. We can take a very high level view of sending an email for instance without having to worry about exactly how MailKit works. Because there is a lot of code to get through, I won’t do too much explaining at this point, we will just run through it. Let’s go!

First, let’s go ahead and create an EmailAddress class. This will have only two properties that describe an EmailAddress.

Now we will need something to describe a simple EmailMessage. There are a tonne of properties on an email, for example attachments, CC, BCC, headers etc but we will break it down to the basics for now. Containing all of this within a class means that we can add extra properties as we need them later on.

Now we need to setup our email configuration. That’s our SMTP servers, ports, credentials etc. For this we will make a simple settings class to hold all of this. Since we are good programmers we will use an interface too!

Now we actually need to load this configuration into our app. In your appsettings.json, you need to add a section at the root for email settings. It should look something like this :

In the ConfigureServices method or your startup.cs, we can now pull out this configuration and load it into our app with a single line.

This allows us to inject our configuration class anywhere in our app.

The final piece of the puzzle is a simple email service that can be used to send and receive email. Let’s create an interface and an implementation that’s empty for now. The implementation should accept our settings object as a constructor.

Head back to our ConfigureServices method of our startup.cs to add in a final line to inject in our EmailService everywhere.

Phew! And we are done. If at this point we decided MailKit isn’t for us, we still have an email service that can swap in and out libraries as it needs to, and our calling application doesn’t need to worry about what’s going on under the hood. That’s the beauty of abstracting a library away!

Getting Started With MailKit

Getting started with MailKit is as easy as installing a Nuget package. Simply run the following from your Package Manager Console :

And hey presto! You now have access to MailKit in your application

Sending Email via SMTP With MailKit

Let’s head back to our email service class and fill out the “Send” method with the actual code to send an email via MailKit. The code to do this is below :

The comments should be pretty self explanatory, but let’s quickly run through it.

  • You can send clear text or HTML emails depending on the “TextFormat” you use when creating your message body
  • MailKit has named it’s Smtp class “SmtpClient” which is the same as the framework class. Be careful if you are using Resharper and the like that when you click “Add Reference” you are adding the correct reference.
  • You should choose to use SSL whenever available when connecting to the SMTP Server

Because we built out our EmailService, EmailMessage and EmailConfiguration classes earlier, they are all ready to be used immediately!

Receiving Email via POP With MailKit

And now the code to receive email via POP.

Again, all rather straight forward.

While we only retrieve a few basic details about the email message, the actual MailKit email object has a tonne of data you can inspect including headers, CC addresses, etc. Extend as you need to!

Free SMTP Server

It’s worth mentioning that if you are a hobbyist with your own website and want to just send a few emails every now and again under your own domain. A great solution that I use for this very blog is MailGun. It has a great free plan that for most people will be more than enough, but also paid plans for when you really need to start sending a lot of email.

This article is part of a series on the OWASP Top 10 for ASP.net Core. See below for links to other articles in the series.

A1 – SQL Injection A6 – Sensitive Data Exposure (Coming Soon)
A2 – Broken Authentication and Session Management A7 – Insufficient Attack Protection (Coming Soon)
A3 – Cross-Site Scripting (XSS) A8 – Cross-Site Request Forgery (Coming Soon)
A4 – Broken Access Control A9 – Using Components with Known Vulnerabilities (Coming Soon)
A5 – Security Misconfiguration (Coming Soon) A10 – Underprotected APIs (Coming Soon)

In previous iterations of this post, I had a big long text wall explanation of what exactly Cross Site Scripting (XSS) was. But after spending hours perfecting it, I think it’s easier to show you a simple screenshot that says it all.

This was simple to do. I have a “search” page for a user, and any query they type I relay back to them in the form of “Search Query {YourQueryHere}”. The code looks like this :

So we are taking whatever the user searched (Or put in the query string) and placing it directly on the page. Thus allowing the user to enter script tags, or really anything they want in there. This is essentially at the heart of what XSS is about. Taking unverified user input, and displaying it wholesale on a webpage.

For the duration of this post, I will refer back to “code I prepared earlier”. This code is up on Github if you want to take a look and test out some XSS yourself. You can download it here.

What Is XSS?

XSS is when a webpage enables an attacker to inject client side scripts (Typically javascript although other types of injections are possible) onto a webpage that is then subsequently shown to other users. Often these scripts seek to steal private data (For example cookies or browser storage), redirect a browser, or sometimes even just trick a user into doing an action that they wouldn’t normally do.

XSS is usually defined into two different types :

Reflected XSS

Reflected XSS is when cross site scripting occurs immediately as a result of the input from a user. An example might be when a user searches, and that search query is displayed immediately on the page.  Typically the danger from XSS comes from the ability to send a link to an unsuspecting user, and that user see something completely unexpected.

Stored XSS

Stored XSS is when you are able to save something to a database or backend store, and have it relayed to users without having to send them a link. If we use an example of a blog that accepts comments on posts. If you are able to store a XSS exploit in a blog comment, then everyone who views that blog post from then on will be affected. Obviously this has the potential to be a much larger exploit than reflected XSS because it doesn’t depend on the user being sent a dodgy link or having to do anything extra on their part.

What Could Someone Do With XSS?


The holy grail is of course to be able to inject script tags on a webpage. With this, the world really is the attackers oyster. They could do something as simple as redirecting the user to a different page (Where they then steal a users credentials), they could inject javascript to build a fake login form right there on the page (Where they then steal a users credentials), or they could even use it to steal a users login cookie (Where they then steal a users credentials). It can be devastating.

While injecting javascript on a page can be nothing short of devastating, protecting your site should be more than just disallowing the word “script” to be submitted anywhere. You can actually do some pretty dangerous stuff without CSS at all.


By injecting styles into a page, an attacker could change the entire layout of the page to trick the user into doing something they don’t want to do. A “clever” exploit I saw in the past was an attacker redesigning a page to trick the user into deleting their own account by moving the delete button around and changing the text (All now possible that you can add “content” inside CSS).

With CSS alone, you can pretty much rewrite the entire website. Let’s take a quick looking using a site I whipped up early. (Again, you can get the source code on Github here). By default it looks a bit like this :


Now let’s try something. Let’s try and inject the following CSS Payload in here :

So the URL will look something like :

Now when we view this URL :


Injecting IFrames is an XSS exploit that can go undetected for quite some time because it can be essentially invisible to end users. IFraming can be as “harmless” as someone trying to rack up views on their own site that contain ads that pay per view, to something as harmful as IFraming a fake login form into the page.


HTML Encoding User Output

Now, if you’ve been looking at my sample code, you would have noticed something a bit iffy. I’m talking about this  Html.Raw(Context.Request.Query["query"]) . And I want to admit, I cheated a little. You see, by default, when ASP.net Core Razor outputs values onto a page, it always encodes them. If we remove this raw tag helper and try and inject a script tag, we instead see this on the page :

So why didn’t this actually run the script tag? It looks like it should right? Let’s actually look at the source code of the page then.

Look at how our script tag actually got written to the HTML. It’s been escaped for us meaning that the script tag hasn’t actually been ran! Hurrah! So for content that gets written directly to the page, we are actually somewhat protected by the framework.

How about other places we are displaying this data? Maybe we are building a SPA and not using ASP.net Core Razor at all. Every javascript library (Even jQuery) will actually encode data for you. But it pays to check whether this is an automatic or manual process, and anywhere you are outputting user input directly into HTML should be triple checked for valid encoding.

An interesting argument to note is that I have come across developers who insist on HTML Encoding things as they are stored in the database, and then displaying them as is on the webpage (Typically when you aren’t using Razor so you don’t get the auto encoding). This will work, but I think it’s a bad practice to follow. When you only encode data when you store it, you leave yourself open for reflected XSS attacks because this data is never stored anywhere (It’s shown directly back to the user).

URL Encoding User Input

While HTML encoding is fine when you are outputting user data directly into HTML. But at times you may need to accept user input and put it into a URL. URL’s do not encode with the same characters as HTML, so you may find yourself trying to override everything with the Raw tag helper. Do not do this! .NET Core has you covered with URL Encode.

To access it, you first need to install the the following nuget package from your package manager console in Visual Studio :

You can then encode your URL’s in a view like so :

Browser Protection

An interesting point to note is that browsers are jumping in to protect users against XSS. With a very simple payload of  <script>alert("this is an XSS")</script> in Chrome, I actually end up with the following :

In saying that, you can basically find cheat sheets online that show you values to try and bypass these filters. A good writeup by a user trying to get around Chrome’s XSS filter can be found here https://blog.securitee.org/?p=37. Essentially, it’s always going to be an arms race and relying on a browser to protect your users would be fool hardy. Not to mention users who don’t update their browsers anyway.

X-XSS-Protection Headers

This is another way of protecting your users that fall into the basket of “great to have, but encode your output please”. Using the X-XSS-Protection header you are able to direct a browser how best to handle any XSS exploits it detects. The header has 4 different values you can user.

X-XSS-Protection: 0
Attempts to disable XSS Protection in the browser (Good if you want to try and test things out).

X-XSS-Protection: 1
Enables XSS protection but if XSS is detected, it will try and sanitize the output (e.g. Encode it or strip the characters). This can be dangerous to do because the resulting HTML could be just as dangerous. See here : http://blog.innerht.ml/the-misunderstood-x-xss-protection/.

X-XSS-Protection: 1; mode=block
Enables XSS protection and will block the page loading all together if any XSS exploit is detected.

X-XSS-Protection: 1; report=<reporting-uri>
This is a chromium only header that will allow you to report back to you any URL’s that were detected in having an XSS exploit.

Realistically the only option you should be using is block as this will protect you the best. You can set the header at the code or server level. For the code level, it’s as easy as adding an additional middleware in your pipeline. Something like so :

If you are interested in further reading, we have an entire article dedicated to just the X-XSS-Protection header, and another on 3 Security Headers That Every Site Should Have.


Cross Site Scripting is one of those exploits that refuses to die, mostly because of people not doing the basics right. As we’ve seen, in ASP.net Core our razor tag helpers are a great out of the box solution to protecting us, and indeed HTML encoding in general no matter the framework will solve a big deal of our problems. Browsers are making big strides in trying to protect people too, but this doesn’t mean developers can suddenly become complacent about their role in protecting end users.

In our next topic from the OWASP Top 10 – 2017, We will be tackling Broken Access Control.

Swagger is an auto-magically generated API documenting tool. It takes any standard Web API project and can generate amazing looking (And functioning) docs without a user having to write a single additional line of documentation. Best of all, it can be as simple as a 2 line setup, or as complex as adding additional info to every single API endpoint to explode the level of info inside Swagger.

Getting Started

For the purpose of this guide, I’m just going to be using the standard ASP.net Core Web API template when you create a new project from Visual Studio. But any existing API will work just fine too!

First off, install the following Nuget package from your package manager console.

Next in the ConfigureServices method of your startup.cs, add the following code to add the Swagger services to your application.

A couple of things to note here, firstly that inside the SwaggerGen lambda you can actually specify a few more details. As an example :

Here we have said for any enum instead of using the integer value, use the string. And for all parameters can we please use CamelCase. The defaults usually suit most, but if there are specific things you are looking for your docs, you can probably find the setting here.

Secondly is obviously the Info object. Here you can specify things like the documentation author, title, and license among other things.

Head down to the Configure method of your Startup.cs.Add a call to “UseSwagger” and a call to “UseSwaggerUI” Both of these should come before the call to UseMVC.

And that’s it! Navigate your browser to https://localhost:{yourport}/swagger  to view your new API documentation.

If you don’t see anything, or it looks a bit odd, jump to the end of this article for a quick trouble shooting session!

XML Comments

The documentation that is auto generated is usually pretty damn good and if you are building a restful API, is usually enough to explain the functions of your API on their own. But there are times when the API needs a bit more explaining. For that, you can use XML Comments on your API action. For example :

If you are using Visual Studio, you can type three forward slashes in a row and it will auto generate a skeleton set of comments for you. Most importantly is the summary and parameter descriptions that are free text. They are invaluable for being able to explain what an endpoint does and what input it expects.

Next you need to force your application to actually generate the XML data that Swagger can then read. Right click on your project in Visual Studio and select Properties. On the panel that opens up, select “Build” on the left hand side. You should see an option for “Output”, and a checkbox for “Xml documentation file”. Tick this box and the setting will be auto filled out for you.

Note that this setting is per build configuration. If you intend to use Swagger remotely (And therefore likely be built in Release mode before deploying), then you should change the Configuration setting up top on this panel to “Release” and then retick the documentation tickbox.

If you are not using Visual Studio, or you are just interested in how things work behind the scenes. Doing all of this just adds the following line to your csproj file.

Next you need to head back to the ConfigureServices method of your startup.cs and add a call to IncludeXmlComments in your Swagger configuration.

Where SwaggerExample.xml is the xml file you set in your csproj/project configuration.

When you view Swagger again you should now see your XML comments displayed inside the documentation.

Up the top right is our description of our endpoint. And in the id row for our parameters, we also have a description value.

Describing API Response Codes

There may be times where your API returns a non “200” response code that you want to provide documentation for. For example an error of 400 if a particular parameter doesn’t fit certain requirements.

The first step is to decorate your actions with a “Produces” attribute that describes all the possible return codes your endpoint will give out. At the same time you can describe that for a given code, what model you will be returning at the same time. So for example if when you return an error 400, you return a particular class that describes the error, you can define that here.

A quick note that you don’t need to specify the return of 200, that is implied, but it’s nice to add anyway. When you view this endpoint in swagger, the non 200 return codes are displayed at the bottom of the endpoint description.

While this lets you know that certain responses are expected, it doesn’t actually give you the reason why they would be returned. For that, we turn again to XML comments.

Now when we view this endpoint in Swagger again we have the descriptions next to the response codes.


I can’t see anything

Check that the nuget package  Microsoft.AspNetCore.StaticFiles is installed in the project. This is required by Swagger to run. If you are unsure, just try installing the package again, this has seriously fixed the issue for me before.

I’m using MVC Core

If you are use the “MVCCore” service rather than just plain MVC. Then you need to explicitly add the API Explorer services. Confused? Head to your ConfigureServices method in your startup.cs. If you see this :

Then you are fine. However if you see this :

Then you need to manually add the ApiExplorer service.

I’m not using “Attribute Routing”

Then Swagger won’t work for you. You must be using attribute routing to use Swagger.

This article is part of a series on the OWASP Top 10 for ASP.net Core. See below for links to other articles in the series.

A1 – SQL Injection A6 – Sensitive Data Exposure (Coming Soon)
A2 – Broken Authentication and Session Management A7 – Insufficient Attack Protection (Coming Soon)
A3 – Cross-Site Scripting (XSS) A8 – Cross-Site Request Forgery (Coming Soon)
A4 – Broken Access Control A9 – Using Components with Known Vulnerabilities (Coming Soon)
A5 – Security Misconfiguration (Coming Soon) A10 – Underprotected APIs (Coming Soon)

In our previous article on the OWASP Top 10 we talked about SQL Injection. Where SQL Injection has a pretty definitive explanation and examples, this next one on “Broken Authentication and Session Management” is a bit more open ended. It covers everything from bad password storage systems (Plain text, weak hashing) to exposing of a session to a user that can then be stolen (For example a session string in a URL) all the way to simple things such as timing out a authenticated session.

As always, while the topics we talk about here are a good start to protecting your ASP.net Core application, they are by no means the end of the road. Especially when it comes to things like hashing of passwords. It’s a game of always staying up to date with the latest threats and updating your application as you go along.

Let’s jump right in!

Password Hashing

It goes without saying that all passwords stored in a database should be hashed and have an individual salt (More on the individual salt later). Under no circumstances should passwords be stored as plain text. When you store plain text passwords, not only do you run the risk of if you get hacked, users on your website having their account stolen, but because people tend to use the same password on multiple sites, you run the risk of then being the source of pain for a user across every website they use.

Using ASP.net Core Identity

If you use ASP.net Core Identity framework, out of the box you are going to have secure password hashes and an individual salt used. Identity uses the PBKDF2 hashing function for passwords, and they generate a random salt per user. Ideally if you are unsure on what you are doing, use the out of the box functionality! Microsoft actually have pretty good documentation on getting the framework up and running.

Rolling Your Own

While using the out of the box ASP.net Core Identity framework is definitely preferable, there may be times where you just need to roll your own. But the roll your own only extends to the C# code that you are using to authenticate, under no circumstances should you “invent” a hashing algorithm of your own to store passwords.

OWASP recommends 4 different one way hashing functions for storing passwords. In order they are Argon2, PBKDF2, scrypt and bcrypt. If you intend to write your own authentication layer you must use one of these.

What Is Salting?

Salting is the act of adding a random string of text to your password before hashing it. In this way, even if the same password is hashed, the resulting hash will be different… Confused? Let’s use an example. I will use the PBKDF2 hashing function for this example.

Let’s say, I am using the password apples4tea . When I hash this I get the result of :  09ADB1C51A54C33C11CD3AE113D820305EFA53A173C2FF4A3150B5EC934E76FF . Now if a second user signs up to my site and uses the same password, they will have exactly the same hash. You can test this yourself by using a PBKDF2 Calculator online calculator here. Why is this bad? Well it means any hacker can essentially “pre-compute” what a password hash would be (For example, taking a list of the most popular passwords today), and simply do a string compare in a database.

Ontop of this, it means that all users who share the same password have the same hash. When one users password is “cracked” or even guessed, anyone else who uses that same password now has their password leaked also.

Now let’s say I add in a random salt for the user and I concatenate it onto the start of the password. The first time round my salt is H786Bnh54A . Hashing the full string of  H786Bnh54Aapples4tea  gives me the hash of  DfsjpycJwtWkOu8UcP8YXC/G09HES8LU+kku0iSllO4= . Another user signs up to the site and a randomly generated hash is given to them of  76HNhg67Ac . Now we hash the salt with the same password and we end up with a hash of  RP62+SmFCJLeQzROTtk5HpMId0zuFtsPeBFuBLpH/Sc=. Now we have the same password, and yet have a different hash.

Quite famously, Adobe had a giant data breach in 2013 that leaked users passwords. The passwords were not per user salted, and worst of all the password “hints” were stored along side the passwords. Meaning if a hint helped you guess one users password, any user using the exact same password would have the same hash in the database! Sophos did a great write up of the breach here. And of course there is an XKCD of the incident too.

If you use ASP.net Identity, the salt is stored with the password in the same column in the database (Because the salt is the same length everytime, we just count the characters as the salt, with the remainder being the hash).In previous iterations of ASP Membership (in .NET full framework), the salt was stored in a separate column. Either are fine as long as the salt is per user, and not application wide.

Exposing Session Identifiers

In previous versions of ASP.net, you could have a “cookieless” session. You would then see URL’s that looked not too dissimilar from the following :  http://www.example.com/(S(lit3py55t21z5v55vlm25s55))/orderform.aspx  . Where the session data is actually contained within the URL rather than in a cookie. This caused havoc for multiple reasons. Imagine sending this URL to a friend, and now they have access to your session data! Even worse is that if you click on any outbound links on this page, the referrer header will be set to include your session.

In ASP.net Core, cookieless sessions were actually never implemented so you won’t see URL’s like this. It doesn’t mean you won’t see people going ahead and trying to implement something similar in a roll-your-own type fashion however. In simple terms, no URL that is given to another user via any means should be able to suddenly impersonate the user.

Sending Data Over Unencrypted Connections

There is actually an entire OWASP Top 10 article coming up about encrypted connections, but it deserves special mention here. Even if your passwords are all hashed with a per user salt, and you don’t expose session identifiers in the URL, it means nothing if you are susceptible to “Man in the middle” attacks. A user connecting to some dodgy airport open wifi could mean they unintentionally broadcast our their clear text password when logging in.

SSL means you are encrypted from the a users computer to the server, no matter the route it takes – dodgy wifi included. Given free SSL providers such as Let’s Encrypt popping up, and even sites like Cloudflare offering free SSL. There is really no reason to not protect your users by taking advantage of SSL.

Lockouts, Timeouts, And More

On a final note, We’ve talked about ASP.net Core Identity so much in this article. But again I would like to point out just how much it enforces good habits. Let’s just take a look at the setup for Identity that you would typically put in your Configure Services method.

Look at the options you have here. There are very good password enforcement options (Although arguments can be made that you shouldn’t go overboard on requiring things like alphanumeric as people tend to then just write them down on pieces of paper…), good options for locking a users account if they continually type in bad passwords, and even requiring email confirmation (Which again, is part of the Identity framework).

And in terms of how the cookies are stored on a users machine, we have these options :

Again all great best practices. A users cookie should always have an expiration by default. An example from OWASP even explicitly states the “public computer” session timeout issue in examples of attacks :

Ontop of that, we should always use HttpOnly cookies where possible. When a cookie is set to HttpOnly, it means it is not accessible via Javascript (And as such, possible XSS vulnerabilities), and can only be accessed when sent as part of a request.

I use these examples because they are great pointers to best practice when it comes to authentication and session management. Even if you decide to roll your own, you should investigate what Identity gives you out of the box so that you can replicate some or all of the functionality, and always keep up to date with the latest improvements to the framework.


Authentication and session management is such a broad topic and one that I think is plagued by slow moving legacy applications. Often when I’ve shown new developers things such as session identifiers in the URL, they can’t imagine why someone would ever do that. “Did people actually ever think that was secure?” is an actual quote from a junior developer I’ve worked with. I think that’s actually the essence of the topic, that we need to be on the forefront of what’s new and secure when it comes to authentication and sessions, so that we stay ahead of the “Did people actually every think that was secure?” curve.

In our next article, we will investigate the never ending fight against Cross-Site Scripting (Or XSS). See you then!

This article is part of a series on the OWASP Top 10 for ASP.net Core. See below for links to other articles in the series.

A1 – SQL Injection A6 – Sensitive Data Exposure (Coming Soon)
A2 – Broken Authentication and Session Management A7 – Insufficient Attack Protection (Coming Soon)
A3 – Cross-Site Scripting (XSS) A8 – Cross-Site Request Forgery (Coming Soon)
A4 – Broken Access Control A9 – Using Components with Known Vulnerabilities (Coming Soon)
A5 – Security Misconfiguration (Coming Soon) A10 – Underprotected APIs (Coming Soon)

OWASP, or the Open Web Application Security Project, is a non profit organization whose purpose is to promote secure web application development and design. While they run different workshops and events all over the world, you have probably heard of them because of the “OWASP Top Ten” project. Every few years, OWASP publishes a top 10 list of the most critical web security risks. While by no means does it mean if you can check off these 10 items, your website is now secure, but it definitely covers your bases for the most common attack vectors on the web.

When I first started programming and heard about OWASP, the hardest thing for me was trying to put that into practical terms. When someone started talking about “CSRF” for example, I wanted to know what does that actually look like in .NET terms, What are the basic principles to protect myself from it, and what (if any) built in systems in .NET are there? This 10 part article series will attempt to answer these questions within the realm of ASP.net Core. By no means will you reach the end and suddenly be immune to all web attacks, but it should hopefully help you understand the OWASP Top 10 from an ASP.net Core standpoint.

Another point to note, I’m going to base these top 10 off the OWASP 2017 Release Candidate. These have not yet been accepted as the official top 10 for 2017, and if they change I will be sure to add additional articles to cover everything off.

So without further ado, let’s get started! Our first item on the list is SQL Injection.

How Does SQL Injection Work?

SQL Injection works by modifying an input parameter that is known to be passed into a raw SQL statement, in a way that the SQL statement executed is very different to what is intended. That might sound like a whole lot of mumbo jumbo, so let’s take a working example.

If you would like the entire working code project on your machine for this post, you can grab everything from Github here. You can still follow along without the code as I’ll post code samples and screenshots the entire way through.

First let’s create a database with two tables. The first table titled “NonsensitiveDataTable” contains some data that we don’t mind sharing out to the user. The second table, aptly titled “SensitiveDataTable” contains users credit cards and social security numbers. Admittedly, a little extreme but bare with me for a bit. Here is how the tables look in SQL Server.

Now let’s say we have an API endpoint. All it does is take a parameter of an “Id”, and we use this to request data from our NonSensitiveDataTable.

This is a rather extreme example and coded rather poorly, but it illustrates the point. Hitting this endpoint to get data, we seem to have no issue.

But just looking at the code we can see something suspect. Notably this line here :

We are passing the Id parameter directly into our SQL Statement. People could type anything in there right? Well, we know that the record of “Mark Twain” is returned when we request the ID of 2. But let’s try this :

Wow…. So why does adding the test “OR id = 1” suddenly change everything. The answer lies in our code above. When we simply pass the id of “2” to our code, it ends up executing this statement.

But when we pass in our OR statement, it actually ends up reading like so :

So here we have managed to modify what SQL statements are getting executed simply by changing a query parameter. But no big deal right? The user will get the wrong data and that’s the end of the that. Well, since we know we can modify the SQL statement. Let’s try something funky. Let’s try this URL :

Uh oh… That doesn’t look good. The query that ran ended up looking like this :

It says, find me the NonSensitiveDataTable where the ID is 999, and while you are at it, link it up to the data from the SensitiveDataTable. Because there was no record with the ID of 999, we jumped immediately to blurting out the SensitiveDataTable, in this case leaking out credit card info.

Now the first thing you are going to ask is… Do I not need to know that the “SensitiveDataTable” exists before I go and run this query. The answer is yes and no. Quite often you will find guesswork can do a tonne for you. If this is an eCommerce site the changes are they will have a “Customers” table and a “Orders” table etc. SQL Injection isn’t as always as easy as copy and pasting in a URL and suddenly you have the keys to the kingdom.

However, let’s try one more thing. Let’s try to get the following query going. It will tell us table names that are in the database.

There you have it, a little less guesswork. We could actually sit there for days throwing commands in here. You will often find SQL Injection “cheatsheets” out on the web with a whole heap of SQL commands to try out. Often with SQL Injections it’s a case of throwing things against the wall and seeing what sticks.

I’ll leave you with one final query you “could” try and run. Let’s say you get frustrated trying to grab data, and you just want to ruin someone’s day. Imagine running the following command :

Here we have just given up, and we are just going to drop a table. Maybe we even grabbed all the data we could, and we just want to make life miserable for the resident DBA. This would be one way to do it for sure!

Now we’ve seen what an SQL Injection looks like, let’s get on to protecting ourselves!

Sanitize Your Inputs

You will quite often find that the first comment on any article describing a recent SQL Injection attack is to “Always sanitize your inputs” (Quickly followed by “Using parameters in your queries is better!” – but more on that later).  Sanitizing your inputs could mean a couple of things, so let’s run through them.

Casting To A Non String Type

In our example code, Because we know our Id is supposed to be an int. Let’s just case it to one.

Perfect! Now if someone tries to add further info to our query string, it’s not going to be parsed to an int and we will be saved!

An even easier example in ASP.net Core would of course just allowing our routing do the work for us.

Now we don’t even need to do any manual parsing. ASP.net Core routing will take care of it for us!

But of course this only works if your query actually is against an integer column. If we really do need to pass strings, what then?

Whitelist/Blacklist/Character Replacement

Honestly, I don’t want to go too deep into this one because I think it’s a pretty error prone way to deal with SQL Injection. But if you must, you can run strings against a whitelist or blacklist of known good values before passing to SQL. Or you can replace all instances of certain characters (Quotes, semicolons etc). But all of these rely on you being one step ahead of an attack. And you pitting your knowledge of the intricacies of the SQL language against someone else.

While languages like PHP have inbuilt functions for “escaping” SQL strings, .NET core does not. Further, simply escaping quotes does not protect you from the root cause of SQL Injection anyway.

Sanitizing your inputs requires you to “remember” to do it. It’s not something that becomes a pattern to follow. It works. But it’s not the ideal solution.

Parameterized Queries

Using Parameters in your SQL queries is going to be your go-to when defending against SQL Injection attacks. Even if you are using an ORM of some sort (Talked about a bit below), behind the scenes chances are they will be using parameterized queries.

So how can we use them in our example project? We are going to change things up a bit and instead query on the “name” field of our NonSensitiveDataTable. Just because it affords us a little bit more flexibility.

Can you see where we have added parameters to our query? So how does this work? Well, with the aid of the SQL Profiler, the actual SQL that is being sent looks like this :

Wow… That’s a heck of a lot different. So what’s going on here? Essentially we are sending the query, but saying “Later on, I will tell you what data to query against”. We pass the exact value we want to query against outside the actual SELECT statement. In this way, our original query is kept intact and it doesn’t matter what a user types into the query string.

The best thing about using Parameters is that they become an easy pattern to follow. You don’t have to “remember” to escape certain strings, or “remember” to use a whitelist. It just works.

Stored Procedures

SQL Stored Procedures are another good way of avoiding SQL Injection attacks. Though stored procedures seem to be out of favour with developers these days, they work similarly to parameterized queries in that you are passing your SELECT statement and your query data in two different “lots” if you will. Let’s quickly create a stored procedure to try out (If you are using the example project from GIT, you already have this SP in your database and you don’t need to run the following).

Let’s create an API endpoint that will run this.

When we hit this endpoint with the SQL Profiler running, we can see the following getting run.

As you can see, it’s very similar to our parameterized query above, where the actual details of our query are sent separately. While it’s rare to see an entire project built around stored procedures these days, they do protect you against SQL Injection attacks.

Use Of An ORM

Now this next part is an interesting part of mitigating SQL Injection attacks. Because in one sense, it becomes a one stop shop for protection. But the reason I’ve put it last is because I think it’s better to understand what’s going on under the hood of an ORM that protects you, and that’s typically parameterized queries.

If you use something like Entity Framework. When you run a Linq query to fetch your data, any linq “Where” statement will be packaged as a parameter query and sent to SQL server. This means you really need to go out of your way to open yourself up to SQL Injection, however it’s not impossible! Almost all ORM’s are able to send raw SQL queries if you really want to. Take a look at this article from Microsoft on sending Raw SQL through Entity Framework Core here. At the very least, using an ORM makes SQL Injection the “default” if you will, rather than something extra added on top.

Lowest Possible Permissions

Remember our drop table command? Just incase you forgot, here it is below :

Will our website ever actually need to drop a table? Unlikely. And yet in our scenario we’ve given it the keys to the kingdom to do whatever it likes. Giving fine grain permissions or the lowest possible permission level is our final step to “stopping” SQL Injection attacks. I’ve put “stopping” in quotes because in reality we are still vulnerable to sensitive data breaches, but our attacker atleast cannot drop tables (They can however still run delete commands!).

Most SQL systems (MYSQL, Postgres, MSSQL) have inbuilt SQL Roles that allow just simple reads and writes to get through, but not to modify the actual table schema. These roles should be used as much as possible to limit any possible attack.


As we’ve seen, SQL Injections can be pretty brutal about leaking sensitive data, and even destroying it. But we’ve also seen that ASP.net Core already has ways we can protect ourselves. While relying on input parsing/type conversion will get us part of the way there, parameterized queries are really our answer. And best of all, there are very few projects these days where you won’t be using an ORM which gives us protection right out of the box.

In our next article in the series, we will be tackling the pretty broad topic of “Broken Authentication and Session Management”. It’s a pretty open ended topic and is more about “practices” related to authentication and sessions rather than a straight forward “Here’s the issue”. I’ll see you then.