3

My boss gave me a list of 8K users in csv format and asking me to create accounts for them. The list have users with gmail, hotmail, and organization email addresses.

I am using MVC 5 and ASP.NET identity 2.

As I am reading CSV file, I am creating the user, and generating a token for them as below:

var userManager = new ApplicationUserManager(new UserStore<ApplicationUser>(_db));

var dataProtectionProvider = new DpapiDataProtectionProvider("Sample");
userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity")); 

string code = userManager.GenerateEmailConfirmationToken(appUser.Id);
var callbackUrl = "http://localhost:2595/Account/Verify?t="+appUser.Id+"&c="+HttpUtility.UrlEncode(code);
SendMail(callbackUrl, appUser.Email);

Once I create a callback URL, I send an email to the user. When the User clicks on the link I sent, user goes to a password registration page, creates password and then logs in with the password he/she created.

Does this approach has any security flaws?

public async Task<ActionResult> Verify(string t, string c)
        {
            if (User.Identity.IsAuthenticated)
            {
                AuthenticationManager.SignOut();
                return RedirectToAction("Index","Home");
            }

            if (t == null || c == null)
            {
                return View("Error");
            }

            var user = UserManager.FindById(t);

            if (user == null)
            {
                return View("Error");
            }

            if (user.EmailConfirmed)
            {
                return View("AlreadyConfirmed");
            }

            var result = await UserManager.ConfirmEmailAsync(t, c);
            if (result.Succeeded)
            {
                user.EmailConfirmed = true;
                UserManager.Update(user);

                ViewBag.Id = t;
                return View("ConfirmEmail");
            }

            AddErrors(result);

            return View();
        } 
  • 1
    Hard to see what's going on here, and would need to see the other half of the process at least. If the token is tied to the user ID, it shouldn't be required as a field of its own. Need more insight. That said, I think the "first three paragraphs" are pretty relevant since I think OP was asking about the security of that particular platform. – AJAr Feb 5 '15 at 21:06
  • once used, URL expires. Someone can not create multiple users with the same identity. My app doesnt use userId anywhere. – DarthVader Feb 5 '15 at 21:06
  • Welcome to Security.SE. Question quality is important and it is valid to edit out narrative aspects to questions so that those posting do not devolve into long stories that do not augment the question being asked. – schroeder Feb 5 '15 at 21:11
  • Wasn't trying to start anything, was upset about something AFK. I've seen your answers on here -- good intuition and a lot of knowledge. Anyway @DarthVader, you might not want to have that open as a means of probing for user ID existence/status. What is the format/length of the ID? Is there no way of validating the token as a process isolated from user ID queries? e.g. a separate table of tokens, reference token in user table which could be used to pull status on each visit until it is verified (then switch status on user table)? – AJAr Feb 5 '15 at 21:17
  • @AJAr this is why first 3 lines are relevant. ASP Identity uses GUID as user Id. and generates very long token which is machine specific. Token is not stored anywhere. I have a user table with user ids as Guid. – DarthVader Feb 5 '15 at 21:21
2

It looks secure enough considering the details you commented about, but I think the best course of action would be to cut the user ID out of the callback and have the user login normally to proceed with authentication if they are not logged in already. The exposure is not too bad as is, so if it is a pain to redirect back to auth page after login then I would say it's fine.

  • Thanks. The problem is i pre-create the users. So they cant really login because they dont have password yet. That s why i am sending over the Guid to identify who the user is. Of course, if the Guid and Token changes, token verification will fail. I also check if the Guid exists in the db. – DarthVader Feb 5 '15 at 21:39
  • Ah, alright. I missed that detail because I was led to believe it was part of an irrelevant narrative. You're saying they don't even know the GUID until you send the e-mail, so I don't see any exposure atm. – AJAr Feb 5 '15 at 21:43
  • so can i trust this approach? – DarthVader Feb 5 '15 at 21:45
  • You can trust that an account will not be verified unless they get the e-mail and click the link, but the authentication logic itself may/may not be a weak point for DDOS exposure, SQL injection, etc. Could use reCAPTCHA to mitigate DDOS risks, but I do not know enough about this library to vouch for its security. I will look into it within the hour, but if it's a popular stack then I'd say you can probably trust it. I should have stuck with just comments considering my lack of experience with this particular foundation. Don't mark this correct — leave it open in case someone is more familiar. – AJAr Feb 5 '15 at 21:49
  • Just hesitant to endorse it since I have not looked into the frameworks, but if you're waiting on a go-ahead to proceed then you're definitely fine in the short order at the very least. – AJAr Feb 5 '15 at 21:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.