Archive

Archive for the ‘Uncategorized’ Category

Preventing over posting or mass assignments vulnerability in ASP.Net MVC


In the previous post, I showed how the over posting or mass assignments vulnerability works in ASP.NET MVC. In this post, I will show how to prevent this vulnerability.

Never use your database object as a parameter for in an action method

Developers may get tempted to use the object they pass to the database. Here is an example

[HttpPost]
[ValidateAntiForgeryToken]
public async Task IActionResult  Create(User user)
{
    if (ModelState.IsValid)
    {
	_context.Add(userl);
	await _context.SaveChangesAsync();
	return RedirectToAction(nameof(Index));
    }
    return View(user);
} 

This is dangerous. With the above code, you will end up hurting the integrity of the data in your database. You should never, in my opinion, expose your database object to the outside world.

Recently, when scaffolding the Controller, the code generator adds a comment to warn developers about the overposting attack I don’t recall seeing it in ASP.NET MVC 4. It may have been added in ASP.NET MVC 5 or ASP.NET Core. The scaffolder also using the BindAttribute when generating the code which will discuss later on in this post.

Use different mode/view model for the Get and Post action methods

I like to use a model or view model which contains a subset of the properties that are in the database model. I use a different view model for the Get and Post request depending on the fields I want to show on the screen or capture from the user. I added new properties to the User model. I also created two view models. One for creating and updating a user (you can different VM for create and update if you want) and one for viewing a user.

public class CreateUserViewModel
    {
	public string Firstname { get; set; }
	public string Lastname { get; set; }
	public string Role { get; set; }
    }
public class UserViewModel
    {
	public int Id { get; set; }
	public string Firstname { get; set; }
	public string Lastname { get; set; }
	public string Role { get; set; }
	public DateTime LastUpdatedDate { get; set; }
    }

I created a branch in the code repository to demonstrate that https://github.com/lajak/SecureAspMvc/tree/OverPostingPreventionSeparateModel

With using the above code, we guarantee that the binder will only limited to the properties we have in the CreateUserViewModel for post request while for get request we have exposing more properties. Btw, creating a separate view model for get is not really necessary if your action method returns a view because your action method is returning the html which will be rendered by the browser. It becomes more crucial to have separate view model for read if your action returns data in json format.

In the controller, we need to map the values from CreateserViewModel to the DB user object.

  public async Task IActionResult Create(CreateUserViewModel user)
{
	var dbUser = new User();
	if (!await TryUpdateModelAsync(dbUser))
	    return NotFound();

	if (ModelState.IsValid)
	{
	    dbUser.LastUpdatedDate = DateTime.Now;
	    dbUser.CreatedDate = dbUser.LastUpdatedDate;
	    _context.Add(dbUser);
	    await _context.SaveChangesAsync();
	    return RedirectToAction(nameof(Index));
	}
	return View(dbUser);
}

Decorate properties with attributes

If you want to use one model, you can decorate the properties you don’t want the binder to bind with the [BindNever] attribute.

public class User
    {
	public int Id { get; set; }
	public string Firstname { get; set; }
	public string Lastname { get; set; }
	public string Role { get; set; }
	[BindNever]
	public DateTime CreatedDate { get; set; }
	[BindNever]
	public DateTime LastUpdatedDate { get; set; }
    }

Properties that are decorated with the BindNever attribute will not be assigned the value that is posted to the server. In other words, the binder will ignore it. There are few potential issues with using BindNever attribute.

  • High maintenance: developers need to remember adding BindNever property when adding new attribute if required and developers need to make sure that BindNever is not removed by mistake from one of the attribute
  • TryUpdateModelAsync: if you decide to have let’s say an admin page where you want administrator to be able to modify those attributes and you create a view model. The TryUpdateModelAsync will still ignore those properties that are decorated with BindNever and you need to assign those properties manually
  • I have read few reported issues that the Binder doesn’t respect BindNever or BindRequired when using the FromBody attribute

Use BindAttribute

One other option is to use the Bind attribute on the action method as such

public async Task IActionResult> Create([Bind("Firstname", "Lastname", "Role")] User user)

With this approach, you need to add the Bind attribute on every action method you want to prevent the over posting attack. You may have to revisit all your action methods every time you add or remove a property to the model.

Conclusion

As we have seen, there are few ways to protect our application from the overposting attack. I prefer to have view models. I feel it is the most flexible option as I can have a different view model per view or action method if required.

 

Advertisements
Categories: Security, Uncategorized Tags: ,

Over posting or mass assignments vulnerability in ASP.Net MVC


In Visual Studio, ASP.NET MVC comes with a great productivity feature called scaffolding. It is a code generation feature that generates a controller, view and the database calls if you are using Entity Framework to communicate to the database. If developers are not careful, they may expose the application to the over posting or mass assignment security vulnerability.

To understand the vulnerability, you need to understand how the Model Binder works in ASP.NET MVC.

The source code for this article is at https://github.com/lajak/SecureAspMvc/tree/OverPosting.

Let’s start with creating some artifacts

Create a new ASP.NET MVC project

Create a new model

        public int Id { get; set; }
        public string Firstname { get; set; }
        public string Lastname { get; set; }
        public string Role { get; set; }

Create UserController

  • Right click on the Controllers folder
  • Click on Add and select Controller
  • On the dialog, select MVC controller with read/write (lets keep it simple and not over complicate the example)
  • In the Create Action method, right click on the View function and click on Add View menu item

  • Fill the dialog as shown below.

On clicking the Add button, Visual Studio will generate a for creating a user. The view will be named create.cshtml and will be located in the Views\Users folder

Run the application and browse to http://localhost/user/create

  • Go back to the UserController
  • On Create Action method that is decorated with the HttpPost attribute, change the parameter type to UserModel and the parameter name to model as shown on the picture below. Also place a breakpoint at the return statement. We don’t have a view for the Index page. But we don’t need for this post.

Run the website in debug mode

Browse to http://localhost/user/create

Fill the form

Click the Create button

The code should break at the breakpoint

Hover over the model parameter and expand the properties

Notice that the Binder mapped the values that you entered in the form to the properties in the object

Now, stop the debugger and go to the Create.cshtml page. Let’s assume that the requirement was to hide the id field. The developer goes and delete the highlighted code

Run the code again and browse to the create method

Notice that the Id field is no longer showing up

If we run the code and populate the fields, the Id property won’t be populated.

As someone who wants to exploit this vulnerability, I can inject that id parameter into the request.

It is easier to use a tool like Fiddler or Burp to intercept the request and add the extra attributes to the payload but we can use the F12 developers tools as well

Click F12

Right click on

<form action="/user/Create" method="post">

Edit as Html and add the following line

<input name="Id" class="form-control" id="Id" type="number" value="111111111" data-val-required="The Id field is required." data-val="true">

Click outside the form attribute

Notice that we can see the field

Fill the other fields and hit create

Notice that the Binder binds the value of the id field to the Id property

Conclusion

We showed a trivial example for the over posting vulnerability. A more realistic example would be showing more or less fields based on the user role. If the developer only uses an if statement in the cshtml code to show fields based on the user role, the developer might be exposing the application to the over posting vulnerability. In the next post, I will show how to protect your application from this vulnerability.

Categories: Security, Uncategorized Tags: ,

Use JQuery to get data from specific html table column


One of the gigs I am currently working on is to load test a web application. I needed some ids to feed my load test scripts but I didn’t have access to the database. I can view the information on a grid on one of the HTML pages. I solved the problem by using JQuery to query the HTML table and extract the ids I need. The id column is the second column on the grid and hence I am using eq(1) in the script below.

Click F12 to open the dev tools and I excuted the following scripts to get the ids  I needed.

$(‘table > tbody > tr’).each(function(i) {

console.log( $(this).find(‘td:eq(1)’).text())

});

 

About Lajak Technologies

A consulting firm in Ottawa, Ontario that provides services related to Microsoft technologies, Team Foundation Server, DevOps practices, security and more. Contact us today to help you solving your complex software problems. Visit us at http://www.lajak.com.

Categories: javaScript, Uncategorized Tags: ,

Install TFS 2015 Build Agent on Premises


In the previous article, I showed how to install and configure Maven on the TFS Build server to build Java applications. This article however applies to either Java or .NET applications. This article is based on the version 1 of Build Agent TFS 2017 has a new build agent that I will blog about in the future.

Download the Build Agent

  • Go to http://<tfsUrl&gt;:8080/tfs/_admin
  • Click on the Agent pools tab
  • Click on Download agent
  • Extract the contents of the zip file to c:\Agents\1

Configure Build Agent as a Service (without executing UI Testing)

TFS Build Agents can run as a service or a user. From my experience, most build agents run as a service. You need to run as a user or interactively, when you have a build that performs UI testing such as Selenium or CodedUI.

  • Open command line
  • C:\Agents\1\ConfigureAgent.cmd


  • I have used the default options. When you enter the tfs url, make sure you add /tfs at the end of the url
  • The default user account is Network Service. You can use domain user account if you need to control the permissions

Configure Build Agent in Interactive mode (to Run Selenium or other UI Tests)

In this case, we need to configure the build agent to run interactively (i.e. answer to install ‘N’ it as a service). I also created a new Pool and called it Interactive to group all the agents that run in interactive mode.

  • Open command line
  • Extract the agent into C:\Agents\2
  • C:\Agents\2\ConfigureAgent.cmd


  • As mentioned above, I am using the new pool which is called Interactive and the agent is not running as a service.
  • When you enter the tfs url, make sure you add /tfs at the end of the url

View Agents on the Web Portal

  • Go to http://<tfsurl&gt;:8080/tfs/_admin/_AgentPool
  • Agents colour coded in green means that that they are online and connected to TFS. Otherwise, they will show in red
  • From this screen you can also disable or delete an agent

About Lajak Technologies

A consulting firm in Ottawa, Ontario that provides services related to Microsoft technologies, Team Foundation Server, DevOps practices, security and more. Contact us today to help you solving your complex software problems. Visit us at http://www.lajak.com.


Categories: TFS2015, Uncategorized Tags: , ,

Configure a TFS 2015 Build Server for Java


Introduction

TFS 2015 comes with a new build engine. It supports building many programming languages such as .NET, Java, Xcode, Android and other languages. You can even have a build agent on Linux. For more information visit https://msdn.microsoft.com/en-us/Library/vs/alm/Build/feature-overview

In this document, I will show how to configure a build server to run Java Maven builds.

Installing maven

System Requirements (Copied from Maven website)

  • Java Development Kit (JDK) Maven 3.3 requires JDK 1.7 or above to execute – it still allows you to build against 1.3 and other JDK versions by Using Toolchains
  • Memory No minimum requirement
  • Disk Approximately 10MB is required for the Maven installation itself. In addition to that, additional disk space will be used for your local Maven repository. The size of your local repository will vary depending on usage but expect at least 500MB.
  • Operating System No minimum requirement. Start up scripts are included as shell scripts and Windows batch files.

Installing Java

Make sure you install the JDK and not just the JRE. Other than that, the installation itself should be straightforward

Create the Environment Variable JAVA_HOME

  • Go to Control panel –> System and Security –> System –>Advanced system settings –> Advanced –> Environment Variables
  • Add new System variable and enter JAVA_HOME as “the Variable name” and jdk path


  • Restart the machine
  • To test, open commandline and type echo %JAVA_HOME%

Download Maven

At the time of writing this document, Maven 3.3.9 was the latest version of Maven. Download Binary zip archive from http://maven.apache.org/download.cgi. I created a folder at c:\JavaTools to have my Java related tools. I extracted the contents of the zip file into c:\JavaTools folder


Test Maven from commandline by typing c:\JavaTools\apache-maven-3.3.9\bin\mvn -v . If you have all the prerequisites, you should see something similar to the following output

c:\JavaTools\apache-maven-3.3.9\bin\mvn -v

Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T11:41:47-05:00)

Maven home: c:\JavaTools\apache-maven-3.3.9\bin\..

Java version: 1.8.0_72, vendor: Oracle Corporation

Java home: C:\Program Files\Java\jdk1.8.0_72\jre

Default locale: en_US, platform encoding: Cp1252

OS name: “windows server 2008 r2”, version: “6.1”, arch: “amd64”, family: “dos”

Create an M2_HOME Environment Variable

  • Create M2_HOME system variable with a value of the Maven folder


  • Restart the machine logout and log back in

What’s Next

In the next blog post, I will show how to install and configure Team Build agents in TFs 2015.

 

About Lajak Technologies

A consulting firm in Ottawa, Ontario that provides services related to Microsoft technologies, Team Foundation Server, DevOps practices, security and more. Contact us today to help you solving your complex software problems. Visit us at http://www.lajak.com.

Categories: TFS2015, Uncategorized Tags: ,

Use PowerShell to call TFS 2015 REST API’s


Few months ago, I was helping a client upgrading from TFS 2010 to 2015. After the upgrade, we were getting a message that says “This feature cannot be used until you configure it for this team project”.

Long story short, I had to upgrade the process template for over 77 team projects. Luckily they were all created using the Agile template 🙂 The process involves running some commands for the collection and others for each team project. That’s when I decided to script it with PowerShell.

In this post, I will show how to use Powershell to call the TFS 2015 REST API. Let me know in the comment section if you are interested in the script to upgrade the process template.

Show me the code

I am using the “Get list of team project” API which is listed at https://www.visualstudio.com/en-us/docs/integrate/api/tfs/projects


$tfsUrl = 'http://tfsUrl:8080/tfs/'
$collectionName = 'DefaultCollection'
$collectionUrl =  "$($tfsUrl)$($collectionName)"
# Construct the Get list of team projects url
$getProjectsUrl = "$($collectionUrl)/_apis/projects/?api-version=1.0"

# Call the REST API using Invoke-RestMethod. -UseDefaultCredentials for using windows authentication
$json = Invoke-RestMethod -UseDefaultCredentials -uri $getProjectsUrl
$formatedJson =  $json | Format-List
Write-Output $formatedJson

The value field contains the data we need. It is just a matter of extracting the project names from the value field

$tpNames = $json.value | select name
Write-Output $tpNames

The above snippet only shows you a list of project names on the screen. Lets do something more interesting. Let’s say we want create a new team for each team project in a collection and call it Database Team

# Create team API
$createTeamUrl = "$($collectionUrl)/_apis/projects/{0}/teams?api-version=2.2"
#Json that contains the data to be POSTed
$Body = @{
            name = "Database"
            description = "Database Team"
        }

# for each team project, create a team called Database by doing a post request to the create team api
$json.value.ForEach({
    Invoke-RestMethod -Method Post -UseDefaultCredentials -uri ($createTeamUrl -f $_.name) -Body (ConvertTo-Json $Body) -ContentType "application/json"
})

Conclusion

It is really convent and powerful to use Powershell or any other scripting language to TFS’s REST API. To learn more about TFS’s REST APIs visit https://www.visualstudio.com/en-us/docs/integrate/api/overview

About Lajak Technologies

A consulting firm in Ottawa, Ontario that provides services related to Microsoft technologies, Team Foundation Server, DevOps practices, security and more. Contact us today to help you solving your complex software problems. Visit us at http://www.lajak.com.

 

 

Fix TFS 2015 Build’s Queue is Empty


Today I wasn’t able to select a queue while creating a build definition or queuing a build using the new build engine that comes with TFS 2015. The drop down was blank.

This problem may occur if you don’t have build queues for your Collection or if you don’t have permission to use the queues in your build definition.

Go to the administration site for your collection

Check if you have queues for Collection

If you do, select your queueà Role à Agent Queue Users à Double click on Agent Queue Users à add users or groups

Otherwise click the “New queue” link to create a new queue

 

About Lajak Technologies

A consulting firm in Ottawa, Ontario that provides services related to Microsoft technologies, Team Foundation Server, DevOps practices, security and more. Contact us today to help you solving your complex software problems. Visit us at http://www.lajak.com.