Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enable user log in from the only one machine(by acquiring CPU Serial) to the ASP.NET-MVC web application

Scenario:

I have web deployed ASP.NET-MVC 5 application with individual user accounts: Identity 2.x. Every user has an e-mail and password to log in the web application via browser, this means that user can log via any device with internet browser.

I would like to enable user logging on condition that he uses exactly the same PC class machine every time he logs in.

I can politely ask user to run any desktop .NET(.exe) application if necessary. I can also ask user to use Chrome browser if the plugin is necessary to achieve this. Literally I can assume anything. The solution might be very uncomfortable, it's fine.

My semi-solution:

  1. Obtain CPU serial number via desktop(let's call it Authorizer.exe) application which will send this unique ID to the ASP.NET-MVC Web Application while logging into it to authorize that user uses certain PC. Authorizer.exe would detect logging into Web Application by sniffing packets going through network. PLUS Detect user's location, which restrains him from moving his computer.

  2. Create desktop app which can be activated once only with unique serial provided from the web application. Login to the ASP.NET-MVC would be possible only if this desktop app is openned.(I have no idea how to do it).

Why do I ask this question:

If somebody steals user's e-mail and passwords I don't want to let the thief being able to login but the most important to me is that I don't want let user to log in from different devices.

like image 534
Yoda Avatar asked Jan 13 '15 17:01

Yoda


People also ask

How will you implement logging in MVC application?

Add log4net in config file config and enter the following details. Add a class Log. cs in the Utilities folder. Now, in the constructor of this class, instantiate logs for monitoring and debugger loggers.

How do I add Windows Authentication to an existing MVC project?

By default MVC apps use Form Authentication and Simple Membership, so you need to make it "false" to run Windows Authentication. Select the project name in Solution Explorer and then in the Property Explorer, click to enable Windows Authentication.


3 Answers

The only solution that I can think of is to issue client certificates, and use certificate authentication in your application.

Managing certificates

To manage certificates you need to implement a PKI, which requires:

  • Get a Certification Authority, needed to issue the certificates (it can be a public CA or you can use self-signed certificates)
  • Issue a Certificate for your web server, using the CA
  • Configure your app to work via HTTPS, and require certificate authentication
  • Issuing certificates for your users, and installing them in their browsers

Ensuring the user cannot move the certificate to other machine

The weak link is the last. You must pay attentiton to how you install, and how you issue the certificate.

Installing the certificate on the user's browser

To install the certificate in the browser. You can:

  • Create a certificate file, that be used to import the certificate in the browser
  • Use a PKI infrastructure (certificate server) that allows a certificate to be requested by visiting a page with a browser, and requires to use the same browser to install the certificate in it, once it's issued (i.e. its request is accepted).

NOTE: in both cases you have to accept the request and issue the certificate or reject it. Certificates are not issued automatically

The first option has a problem: if you send the certificate to your user he'll be able to install it in any machine, any number of times. To solve this problem you'd need to get access to your user's machine, copy the file, install it, and delete it. The second option solves this problem.

The second option is safer. But a user with good knowledge can still recover the file issued by the server in this process, and install the certificate in a different place.

Making the private key non-exportable

Another very important point to take into account is that, when you issue a certificate there is generally an option that allows to make its private key exportable. If you set this option, the user can export the PK from the browser where it is installed, and install it somewhere else. Obviously you want to avoid this. So, disable this option.

With this option, the user can still export the certificate, but without its private key, so it can't be installed somewhere else.

Setting up the PKI

I don't give additional details on how to setup the PKI, because it depends largely on the infrastructure (OS and version). If you want to know more about certificates and PKI the wikipedia entry for "X.509" and wikipedia entry for PKI. Then you can look for additional information on setting a PKI in your particular infrastructure (OS).

Security of this system

You can rest assure this system is really safe: for example, in my country you can identify yourself by this means to make a lot of "official" things, like declaring and paying taxes.

Revoking certificates

And, if you're wondering what happens if you want to reject access to a user that already has a certificate. The answer is that you can revoke a certificate whenever you want, so that the server won't allow your user to authenticate with his certificate, because it's revoked.

User and machine safety

And another thing that can worry you is that other user takes the same machine and logs to your application. It's harder thanit looks like for this reasons:

  • the certificate is only available when you log to he machine with the same user that installed it
  • when installing the certificate you can make the OS to request a password when someones wants to use the certificate
  • you can make your app to have double authorization:
    • first, the certificate authorization (this is, in fact, handled by IIS itself)
    • second, ask for a username and password (or use the certificate's user name, and ask for an additional password associated to the user)

Edit: the dirty solutions, and the queen of all them, evercookie, that stores data in 12 different thinkable and unthinkable places

I've seen a lot of anwsers that propose using a "magic way" of identifying the user's machine, without him knowing and accepting it, and, or that can be broken by some user actions. Those solutions are unstable, and can even be not legal. Besides, none of the explained solutions is reliable or easy to implement, but the one that I'll so you at the end of my answer. But before this, allow me to explain why I prefer the certificates solution.

Installing an issued certificate is something which isn't hidden from the user, and that can't be broken unless the user deletes the certificate on purpose. The user can be informed that he needs the certificate to access the application, so you're neither cheating, nor making "magic" to identify his machine. It's a clean, supported, and documented solution. Besides a certificate cannot be caracked or hacked (in an strict sense, everything can be cracked or hacked, but this is way too hard to crack). Apart from this, the same certificate can be shared by all browsers, because it's not installed in the browser, but in the machine's certificate store. So, even if the user opens the application with a different browser, the certificate will still be there. And it's very easy to check if the problem to authenticate it's a missing certificate(or something related to it).

However, if you still prefer to implement a solution that can identify your user's machine without him approving it,or without explaining how it works, you can use "supercookies". If you google for thister you'll find in a lot of places that this exploits Flash storage. Or even Flash + HTML5 storage. Or it can use even many other places to store the required information. But you'll see that this techniques are frowned upon. And can be against the low and make you get into trouble. However, that said, if you still want to do this kind of "dirty" thing, you can use evercookie. It's implemented in JavaScript and you can see the information and donwload the code from this link:

  • http://samy.pl/evercookie/

Disclaimer: if you use this evil thing and get into some kind of trouble, don't blame on me! I told you!

like image 66
JotaBe Avatar answered Oct 04 '22 04:10

JotaBe


Your solution is very difficult and requires a lot of work. I'd suggest you something much more simple.

First of all, you add a binary field 'FirstTime' to users db and init it with 'true' by default. When user make log in first time you drop him a cookie (I'd encrypt it for the better security) and change the field in user's record to 'false'. When user log in again you check this cookie and disallow him to log in if cookie not exists. Therefore, you let every user to log in one time from any place, and then he or she can log in only from the same browser and same machine.

See the following pseudo code:

Login (Email, Password)
{
    if (FirstTime)
    {
        DoLogin();
        SetCookie();
        FirstTime = false;
    }
    else
    {
        if (GetCookie())
            DoLogin();
        else
            ConfirmError();
    }
}

An only weak point in this solution is the theoretical possibility that user may try to copy the cookie to another machine. It, however, requires from your users to be a quite good hackers, and from your description I suppose that they are not.

UPDATE:

I thought much about you problem and I'll try to suggest you an improved solution which is still easy in implementation, not requires a weeks of hard work, not costs a lot of money and not forces the customers to fulfill the complicated operations.

The idea is to combine a number of the client detection methods, while it's probably not so difficult to pass around each one them, but it's really problem to pass around all of them together.

So, you can do three things:

  1. Set encrypted cookie. Even it's not a big problem to copy, it's one more operation the potential 'hacker' should not forget to do.
  2. Duplicate it in the browser Local Storage. Again, it's possible to trick, but nobody said the cheater that he need do it.
  3. Use the browser fingerprinting techniques. For more information on it read here and here. At least you can check the User Agent, HTTP Headers, Screen Size and Color Depth and the Browser Plugin Details. The probability that two browser's fingerprints will be close enough is low even inside the same organization.

All this information you can store per user in your DB and the combination of these factors will provide the reliable decision base. For example, if somebody has a cookie but the Local Storage record is missed, it's obvious that the cookie was copied. Disallow access and delete the cookie. Let's imagine the cheater came back to the original computer, found a Local Storage record, copied it as well and try to connect again... but it's already no cookie here! And don't forget about the browser fingerprint, which is more difficult to fabricate. If you limit the number of unsuccessful connection attempts during the certain period of time, it will be REALLY difficult to break your protection.

like image 20
Alexander Dayan Avatar answered Oct 04 '22 02:10

Alexander Dayan


Checking any hardware info, such as CPU Id is imposibble with javascript, because it can't run out of browser's sandbox. Doing it with c# is possible though:

    public static string GetCpuId()
    {
        var mbs = new ManagementObjectSearcher("select ProcessorId from Win32_processor");
        var mbsList = mbs.Get();
        var cpuId = "";
        foreach (var mo in mbsList)
        {
            cpuId = mo["ProcessorId"].ToString();
            break;
        }
        return cpuId;
    }

But there's no sence in it. Imagine user tries to log in using email and password. Somebody's sniffing traffic and steals user's credentials. So he wants to sign in to your web app and realizes it's impossible because he also needs CpuId. Do you really think it's to hard too steal it together with password and after that do a fake sign in request to get cookie? No it's not. Having desktop authorize application is even worse idea, cause any 10-year old cracker will hack auth tool in a few seconds.

IMHO, good way is to implement some kind of 3D-secure, e.g. :

  1. User enters his credentials on a sign in page
  2. Application sends text message with some secret code to user's cell phone
  3. User enter's code
  4. Profit!

Also you need to use HTTPS for all secure-sensitive traffic.

If you don't want to let user use application from any other device - then you'll need to implement some api on server-side, that can be used by desktop application (client-side) with integrated hardware licensing

like image 24
Sergio Avatar answered Oct 04 '22 04:10

Sergio