Skip to main content

Non-encrypted confidential information - Credentials

Need

Secure storage of credentials

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.AspNetCore.Mvc.ViewFeatures for rendering views and managing view data in ASP.NET Core MVC
  • Usage of Microsoft.AspNetCore.Mvc.Core for building web applications with ASP.NET Core MVC

Description

Non compliant code

public class User
{
public string Username { get; set; }
public string Password { get; set; }
}

public class UserController : Controller
{
public IActionResult Login(User user)
{
if (user.Username == "admin" && user.Password == "password123")
{
return View("Home");
}
else
{
return View("Error");
}
}
}

The above code is a simple representation of a user login functionality in an ASP.NET Core application. The User class has two properties: Username and Password. The UserController class has a Login method that accepts a User object and checks if the username is "admin" and the password is "password123". If the credentials match, it redirects the user to the home page. Otherwise, it redirects them to an error page.

The vulnerability in this code is that the password is stored and checked in plain text. This is a severe security risk because anyone who has access to the source code can see the credentials. If an attacker gains access to the source code, they can easily log in as the admin user. This vulnerability is known as "Non-encrypted confidential information - Credentials".

It is a best practice to never store passwords in plain text. Instead, passwords should be hashed and the hash should be stored. When checking the password, the provided password should be hashed and compared to the stored hash. This way, even if an attacker gains access to the source code or the database, they cannot determine the original password from the hash.

Steps

  • Store passwords securely using a strong hashing algorithm.
  • Use a salt value when hashing passwords to add an extra layer of security.
  • Implement password complexity requirements to ensure strong passwords are used.
  • Use a secure password storage mechanism such as ASP.NET Core Identity or a third-party library.
  • Avoid hardcoding passwords in the source code.
  • Consider using a secure credential management system to store and retrieve passwords.
  • Encrypt sensitive information in transit using HTTPS.
  • Implement secure authentication mechanisms such as multi-factor authentication.

Compliant code

public class User
{
public string Username { get; set; }
public string Password { get; set; }
}

public class UserController : Controller
{
private readonly UserManager<User> _userManager;
private readonly SignInManager<User> _signInManager;

public UserController(UserManager<User> userManager, SignInManager<User> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;
}

public async Task<IActionResult> Login(User user)
{
var result = await _signInManager.PasswordSignInAsync(user.Username, user.Password, false, false);

if (result.Succeeded)
{
return View("Home");
}
else
{
return View("Error");
}
}
}

The updated code now uses ASP.NET Core Identity for user management and authentication. The UserManager&lt;User> and SignInManager&lt;User> services are injected into the UserController through the constructor. These services provide methods for user management and authentication, including password hashing and salting.

In the Login method, the PasswordSignInAsync method is used to validate the user's credentials. This method checks the provided username and password against the hashed and salted password stored in the database. If the credentials are valid, the method returns a result indicating success, and the user is redirected to the Home view. If the credentials are invalid, the method returns a result indicating failure, and the user is redirected to the Error view.

This approach ensures that passwords are not stored in plain text in the source code or the database. Instead, passwords are hashed and salted using a strong hashing algorithm, and the hashed and salted password is stored in the database. This makes it much more difficult for an attacker to obtain the user's password, even if they gain access to the database.

In addition, the use of ASP.NET Core Identity provides other security features, such as password complexity requirements and account lockout after a certain number of failed login attempts. These features help to further protect user accounts from unauthorized access.

References