Preventing Common Web Application Vulnerabilities with ASP.NET MVC and Entity Framework

Dumal Aluthdeniya
7 min readMay 23, 2020

Hello, I’m going to talk about three common web application vulnerabilities that every web developer must be familiar with.

I’m going to talk about SQL injection, cross-site scripting, and cross-site request forgery.

SQL Injection

Allows an attacker to execute malicious SQL statements in your application.

For example, they can get the list of all users, or delete records and so on. Depending on how the attack is done and how much vulnerability is there the impact can vary. So how does it work? Imagine in our application we have a code like this.

var users = "select * from users where userId = " + userid;

We get the user with the given ID and this ID is to be supplied as an input. It could be a text box where the user enters a number or it can be a hidden field or a query string.

Now the problem with this code is that the SQL statement is generated at runtime. And that is based on the input to the application. So the attacker can use this opportunity to modify the final SQL statement at runtime.

So in this example they can supply an input like this.

1234 or 1=1

So here it doesn’t matter if there is a userId with the value 1, 2, 3, 4 in the database or not. The important thing is the second part of this input: or 1 = 1. This statement is always true, so as a result our SQL statement will return all users from the database.

The way to protect against SQL injection is to use parameterized queries instead of string concatenation. So in this case if we changed our SQL statement to something like this,

var users = "select * from users where userId = @userId";

then the attacker could not modify the final result. Whatever they pass as the input will be stored in userID parameter.

Do we have this vulnerability if we use Entity Framework? No. Because we are not generating SQL at runtime, instead we are using entity framework and we let entity framework generate the SQL statements.

_context.Employees.Add(employee);

We simply add an object to a DbSet and entity framework will take care of the rest. But if instead we used the SQL query method of a DbSet and generated SQL statements using string concatenation like this,

_context.Employee.SqlQuery("select * .." + input);

we could have SQL injection vulnerability.

Cross-site scripting (XSS)

Enables an attacker to execute a malicious script on the victim’s computer

Then they can steal the user’s cookies and hi-jack their session. Depending on the sophistication of the attack they can also get access to the user’s Geo location, web cam, file system, and so on.

So how does it happen? The attack starts by the attacker inserting malicious JavaScript into the pages of a trusted website. For example, in a forum they can reply or create a post, and include some JavaScript there. Later when the victim visits the pages of this trusted website, the malicious script is loaded along with the page content and executed on the user’s browser.

How can we prevent this? The primary way to disable cross-site scripting attacks is to escape content, which tells the browser to treat the content as a simple string and not interpret it in any other way. If the attacker puts a script on your page the victim will not be affected because the browser will not execute the script if it’s properly escaped.

Do we have this threat if we use ASP.NET? First of all, ASP. NET MVC applications by default, have a protection mechanism that detects JavaScript in the input fields of a form. So unless you explicitly disable this mechanism in web. config, that’s going to stop the attacker from exploiting this vulnerability in the first place. Also Razor views by default automatically escape content. The only exception is if you’re using Html. Raw method.

Cross-Site Request Forgery (CSRF)

Allows an attacker to perform actions on behalf of a user without their knowledge

How does it happen? Imagine PayPal is vulnerable to CSRF attacks, and here’s the URL to transfer money from one account to another.

paypal.com/transfer-money

So when the victim logs into their PayPal account and fills out the form to send money to someone a POST request will be sent to this URL. Let’s imagine that the body of the request contains two fields:

Now the attacker can create a page and somehow try to get the victim to visit that page. Perhaps promising to offer something for free, or get a prize. The possibilities are endless. On that page there is a button that is supposed to give the victim that ultimate reward. When the victim clicks that button a POST request will be sent to the money transfer end point on PayPal, but with modified body. So the attacker can put their own account ID in the target amount field and set the amount to whatever they’d like to get from the victim.

Now, at this point if the victim happens to have an active session on PayPal, when they click this button a request will be posted to PayPal which will cause a money transfer from their account to attackers account.

And interestingly everything looks legitimate here. If PayPal tries to trace the issue all the records show that the victim did transfer the money just as if they filled out the form and clicked the transfer button. That’s why this attack is called Cross-side request forgery. Because the attacker forges the request on another site.

Preventing CSRF Attacks

Now how can we prevent this? Preventing CSRF attacks in ASP. NET MVC is pretty easy.

The framework itself has taken care of all the complexity. All we have to do is call Html. AntiForgeryToken method in our forms, and then decorate the target action with ValidateAntiForgeryToken attribute.

//view
using(Html.BeginForm("Create", "Home")
{
@Html.AntiForgeryToken()
//more code...
}
//controller
[ValidateAntiForgeryToken]
Public ActionResult Create()
{
}

If you have a form like this then go to the form and inspect element. Take a look here.

Here’s our form and here we have a hidden field, that includes a random token. When we call Html. AntiForgeryToken, ASP. NET MVC is going to put a hidden field here.

But that’s the first part. It’s also going to create a cookie that includes the encrypted version of this token. So let’s go to resources > cookies > local host look, we got RequestVerificationToken.

And the value you see here is the encrypted version of our token. When we post this form to the server, since we decorated our action with RequestVerificationToken, ASP. NET MVC is going to compare these two values. It’s going to get the hidden field from the form, encrypt it and compare it with the value in the cookie. If they match that’s a legitimate request.

Otherwise it’s a CSRF attack. Why? Because the attacker may be able to steal the user’s cookie, but they won’t have access to the hidden field. The only way to get the hidden field is to get the user visit to trust the page. Not the malicious page. Which is completely opposite of the idea of a CSRF attack.

We can simulate this scenario. You can to fill out the form, but remove the anti-forgery token in the hidden field.

And finally click save. The required anti-forgery form field is not present.

So we cannot create without having a valid anti-forgery token.

Summary

Alright now let’s quickly review the key points. Here we discussed about three most common security attacks in web applications. Again there are many other attacks out there, and new ones come out all the time, but what we explored are the bare minimum that every web developer should know.

· SQL Injection

Allows an attacker to execute malicious SQL statements

That’s possible if you’re building queries dynamically at runtime using user’s input

The workaround is to use parameterized queries, and not using string concatenation.

Use Entity Framework and work directly with a DbSet. Entity framework will take care of the query generation.

· Cross-site scripting

Enables an attacker to execute a malicious script on the victim’s computer.

The way to do this is by inserting Javascript into data entry forms

ASP. NET MVC detects Javascript in the request body and immediately stops the request.

Razor Views escape content so they won’t be executed by the browser

· Cross-site request forgery (CSRF)

Allows an attacker to perform actions on behalf of a user without their knowledge

Disabled it by using an anti-forgery token.

--

--