kseen
kseen

Reputation: 397

What's the best way to leave a backdoor in ASP.NET Identity app?

I'm a developer of a company's internal client system and there are some situations I have to login into the system using a user account to check for a bug or something. Since passwords are encrypted I can't just look up them in the DB and get the access.

The best thing I invented is to use a query parameter flag like ?heyThisIsAdmin=soJustLetMeInWithoutAnyPasswords which allows me to enter any password and log in.

But I quite understand the security concerns. Could you advise me some ways of achieving what I want but more robust and safe?

Upvotes: 0

Views: 1026

Answers (2)

Will Prosser
Will Prosser

Reputation: 35

ASP has the ability to handle this through impersonsation. You'll need to implement methods to both set and disable imperonsation.

The way I implemented this was to only decorate the SetImpersonation action with [Authorize] attributes to only allow the Admin user role to impersonate users.

Here's an example for MVC:

To set the impersonation

  [Authorize(Roles = (AccountController.Permissions.SUPER_USER))]
    public ActionResult ImpersonateUser(string userName)
    {
        string originalUsername = LoggedInUser.Email;

        ApplicationUser impersonatedUser = UserManager.FindByNameAsync(userName).Result;

        var impersonatedIdentity = UserManager.CreateIdentityAsync(impersonatedUser, DefaultAuthenticationTypes.ApplicationCookie).Result;
        impersonatedIdentity.AddClaim(new Claim("UserImpersonation", "true"));
        impersonatedIdentity.AddClaim(new Claim("OriginalUsername", originalUsername));

        AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
        AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = false }, impersonatedIdentity);

        return RedirectToAction("Index", "Home");
    }

And to revert the impersonation (this action needs to be accessible by the imperonsated user)

public ActionResult RevertImpersonationAsync()
    {
        if (!HttpContext.User.IsImpersonating())
        {
            // we could throw an exception here, but it might be more prudent to just silently fail, keeps this feature quiet from snoopers

            //throw new Exception("Unable to remove impersonation because there is no impersonation");

            return RedirectToAction("Index", "Home");
        }

        var originalUsername = HttpContext.User.GetOriginalUsername();

        var originalUser = UserManager.FindByNameAsync(originalUsername).Result;

        var impersonatedIdentity = UserManager.CreateIdentityAsync(originalUser, DefaultAuthenticationTypes.ApplicationCookie).Result;

        AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
        AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = false }, impersonatedIdentity);
        return RedirectToAction("Index", "Home");
    }

Upvotes: 0

Edouard
Edouard

Reputation: 68

As you said, the solution you propose is not safe at all as any person reading the code or knowing the secret would use the magic query string to use this super power as well.

A better solution could be to create yourself an account on the client platform, but with a special flag on it allowing you to impersonate user accounts (or just see what they see). Such mechanism would require some development of course.

Please note that even with this solution the trick could only be done once your are already logged in. To increase security you could also require a 2nd factor for your authentication (email, SMS, TOTP...)

You need to see what you're trying to achieve here as a feature of your app, not a backdoor. You should be able to explain how it works to anyone without exposing your app. Because the strength of it is in:

  • your password
  • your second factor if any
  • the fact that you have THE flag set on your account

Upvotes: 1

Related Questions