Business information leak - Personal Information - C-Sharp

Business information leak - Personal Information - C-Sharp

Need

Protection of personal information from unauthorized access or leakage

Context

  • Usage of C# 7.0 for modern and efficient programming in the C# language
  • Usage of Microsoft.AspNetCore.Mvc for building web applications using the MVC pattern in .NET Core

Description

Non compliant code

        public class User
{
    public string Id { get; set; }
    public string PhoneNumber { get; set; }
}

public class UserController : Controller
{
    [HttpPost]
    public IActionResult CreateUser(User user)
    {
        // Storing user information in the source code
        var userId = "1234567890"; // Real ID
        var userPhoneNumber = "123-456-7890"; // Real Phone Number

        return Ok();
    }
}
        
        

The above code is a representation of a simple user creation endpoint in an ASP.NET Core application. The User class holds two properties, Id and PhoneNumber, which are expected to be provided when creating a new user.

The vulnerability lies within the CreateUser method of the UserController. Here, the developer has hard-coded real user information
- an ID and a phone number
- directly into the source code. This is a major security risk, as anyone with access to the source code can now view this sensitive information.

Hard-coding sensitive information into the source code is a bad practice and can lead to serious data leaks and security breaches. This is especially true for version control systems where the source code is stored, as every change is tracked and can be viewed at any time.

This vulnerability can be exploited by an attacker who gains access to the source code, allowing them to steal the hard-coded information and potentially use it for malicious purposes.

Steps

  • Do not store sensitive information such as real ID numbers and phone numbers in the source code.
  • Implement a secure data storage mechanism such as a database to store user information.
  • Use appropriate encryption techniques to protect sensitive data at rest and in transit.
  • Implement access controls and authentication mechanisms to restrict access to sensitive information.
  • Follow security best practices and guidelines provided by the ASP.NET Core framework.

Compliant code

        public class User
{
    public string Id { get; set; }
    public string PhoneNumber { get; set; }
}

public class UserController : Controller
{
    private readonly IUserService _userService;

    public UserController(IUserService userService)
    {
        _userService = userService;
    }

    [HttpPost]
    public async Task CreateUser(User user)
    {
        // Storing user information in the database
        var result = await _userService.CreateUser(user);

        if (result)
        {
            return Ok();
        }

        return BadRequest();
    }
}

public interface IUserService
{
    Task CreateUser(User user);
}

public class UserService : IUserService
{
    private readonly ApplicationDbContext _context;

    public UserService(ApplicationDbContext context)
    {
        _context = context;
    }

    public async Task CreateUser(User user)
    {
        _context.Users.Add(user);
        return await _context.SaveChangesAsync() > 0;
    }
}
        
        

The updated code no longer stores sensitive user information in the source code. Instead, it uses a secure data storage mechanism, a database, to store user information.

The User class remains the same, representing the user with properties for Id and PhoneNumber.

The UserController class now has a dependency on IUserService, which is injected through the constructor. The CreateUser method now calls the CreateUser method of the IUserService to store the user information in the database.

The IUserService interface defines a contract for user services, with a CreateUser method that takes a User object and returns a Task<bool> indicating the success or failure of the operation.

The UserService class implements IUserService, taking a dependency on ApplicationDbContext (representing the database context) through its constructor. The CreateUser method adds the user to the Users DbSet and saves the changes asynchronously, returning a boolean indicating whether or not the operation was successful.

This approach ensures that sensitive user information is securely stored in the database and not in the source code. It also allows for the implementation of additional security measures such as encryption and access controls.

References