In a previous chapter on testability, we mentioned the method of defensive programming. Even though this method is not strictly a security feature, it happens to help with creating a robust interface. Such interfaces, in turn, increase the overall security of your system.
As a good heuristic, you can treat all the external data as unsafe. What we mean by external data is every input coming to the system via some interface (either a programming interface or user interface). To denote this, you can go as far as prefixing the appropriate types as Unsafe, as follows:
RegistrationResult registerUser(UnsafeUsername username, PasswordHash passwordHash)
{
SafeUsername safeUsername = username.sanitize();
try
{
std::unique_ptr<User> user = std::make_unique<User>(safeUsername, passwordHash);
CommitResult result = user->commit();
if (result == CommitResult::CommitSuccessful)
{
return RegistrationResult::RegistrationSuccessful...