Secure data masking
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace VulnerableApp.Controllers
{
[ApiController]
[Route("[controller]")]
public class UserController : ControllerBase
{
private readonly ILogger _logger;
public UserController(ILogger logger)
{
_logger = logger;
}
[HttpPost]
public IActionResult Post([FromBody] User user)
{
// Here we are directly using the user object without any masking
Console.WriteLine("Username: " + user.Username);
Console.WriteLine("Password: " + user.Password);
return Ok();
}
}
public class User
{
public string Username { get; set; }
public string Password { get; set; }
}
}
The above code represents a simple ASP.NET Core backend application that has a vulnerability related to insecure functionality
- masking. The application has a
UserController
that accepts POST requests. The POST request is supposed to receive a
User
object from the request body.
The
User
object contains a
Username
and
Password
property. When a POST request is made to the
UserController
, it directly prints out the
Username
and
Password
to the console without any form of masking.
This is a vulnerability because it exposes sensitive information, such as the user's password, in plain text. Anyone who has access to the console logs can see this sensitive information. This could potentially lead to unauthorized access if the logs fall into the wrong hands.
The application should mask or encrypt sensitive data to prevent it from being exposed in plain text. In this case, the password should be hashed or masked before being logged or stored.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Security.Cryptography;
using System.Text;
namespace VulnerableApp.Controllers
{
[ApiController]
[Route("[controller]")]
public class UserController : ControllerBase
{
private readonly ILogger _logger;
public UserController(ILogger logger)
{
_logger = logger;
}
[HttpPost]
public IActionResult Post([FromBody] User user)
{
// Here we are directly using the user object without any masking
// Masking the password before logging
var maskedPassword = new String('*', user.Password.Length);
_logger.LogInformation("Username: " + user.Username);
_logger.LogInformation("Password: " + maskedPassword);
// Hashing the password before storing it
user.Password = ComputeSha256Hash(user.Password);
return Ok();
}
static string ComputeSha256Hash(string rawData)
{
// Create a SHA256
using (SHA256 sha256Hash = SHA256.Create())
{
// ComputeHash - returns byte array
byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData));
// Convert byte array to a string
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
builder.Append(bytes[i].ToString("x2"));
}
return builder.ToString();
}
}
}
public class User
{
public string Username { get; set; }
public string Password { get; set; }
}
}
The updated code now includes data masking and hashing techniques to protect sensitive information.
In the
Post
method, the user's password is masked before it is logged. This is done by replacing each character of the password with an asterisk (*). This way, even if the logs are accessed, the actual password will not be revealed.
Next, the password is hashed using the SHA256 algorithm before it is stored. Hashing is a one-way function that scrambles the original data (in this case, the password). Even if the hashed password is accessed, it is extremely difficult to reverse-engineer the original password from the hashed value.
The
ComputeSha256Hash
method is used to hash the password. It takes a string as input and returns the hashed value as a hexadecimal string.
By implementing these changes, the system now masks sensitive data and uses secure methods to store and transmit such data, thereby fixing the insecure functionality vulnerability.