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.