Implementation of robust data validation for numbers
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.
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.