Lack of data validation - Numbers
Need
Implementation of robust data validation for numbers
Context
- Usage of C# 7.0 for modern language features and enhancements
- Usage of Microsoft.AspNetCore.Mvc for building web applications with ASP.NET Core
- Usage of Microsoft.EntityFrameworkCore for data access and object-relational mapping (ORM) in .NET applications
Description
Non compliant code
public class ProductController : Controller
{
[HttpPost]
public IActionResult Create(string name, int price)
{
var product = new Product(name, price);
_context.Products.Add(product);
_context.SaveChanges();
return Ok();
}
}
In the above code, the Create
method of the ProductController
class is vulnerable due to the lack of data validation. The method accepts a name
and a price
as parameters and directly uses these to create a new Product
object, which is then added to the Products
collection in the _context
object and saved to the database.
The vulnerability lies in the fact that there is no validation performed on the price
parameter. If a negative number, zero, or an unreasonably large number is passed as the price, the method will still proceed to create the Product
object and save it to the database. This could lead to incorrect data being stored, which could break the business logic and negatively impact the business.
For example, if a negative price is saved, this could lead to incorrect calculations when determining the total cost of a set of products. Similarly, if an unreasonably large price is saved, this could lead to incorrect calculations that exceed the maximum value that can be stored in an integer, causing an overflow error.
Furthermore, the lack of validation could also open up the possibility for SQL Injection attacks if the price
parameter is used in a SQL query.
Thus, it's crucial to add proper data validation to ensure that only valid prices are allowed to be saved to the database.
Steps
- Implement input validation for the 'name' parameter to ensure it is not empty or null.
- Implement input validation for the 'price' parameter to ensure it is a valid positive number.
- Handle validation errors and return appropriate error responses to the client.
- Consider using data annotations or a validation library to simplify the validation process.
- Ensure that the validation is performed both on the client-side and server-side to provide a robust defense against malicious input.
Compliant code
using System.ComponentModel.DataAnnotations;
public class ProductModel
{
[Required]
public string Name { get; set; }
[Required]
[Range(1, int.MaxValue, ErrorMessage = "Please enter a value bigger than {1}")]
public int Price { get; set; }
}
public class ProductController : Controller
{
[HttpPost]
public IActionResult Create([FromBody] ProductModel productModel)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var product = new Product(productModel.Name, productModel.Price);
_context.Products.Add(product);
_context.SaveChanges();
return Ok();
}
}
The code above fixes the vulnerability by adding data validation to the Create
method in the ProductController
class.
Firstly, a new ProductModel
class is created to represent the incoming product data. This class includes two properties: Name
and Price
. Both properties are decorated with the [Required]
attribute to ensure that they are not null or empty. The Price
property is also decorated with the [Range]
attribute to ensure that it is a positive number.
In the Create
method, the [FromBody]
attribute is added to the productModel
parameter to bind the incoming JSON data to the ProductModel
object. Then, the ModelState.IsValid
property is checked to see if the incoming data is valid according to the data annotations in the ProductModel
class. If the data is not valid, the method returns a BadRequest
response with the validation errors.
If the data is valid, a new Product
object is created and added to the database. The method then returns an Ok
response to indicate that the product was successfully created.
This approach ensures that only valid data is processed by the application, thereby preventing the business logic from being broken by invalid or malicious input.