Device identification authentication like in google / facebook - html

How to identify user's device on authentication -- such that second factor auth (such as SMS) can be enforced if user is logging in from an unknown device? I've seen google and facebook has this feature, and they're not using a simple IP check -- if I have two devices on the same network, it can still detect if I tried logging in from an unknown device.
Especially on websites -- as far as I know we can only get user's IP, and other information on HTTP headers, but how do we identify the user's device securely?

You could use cookies - if the user doesn't have the appropriate cookie, then require a successful two factor authentication?
You could also consider browser fingerprinting in combination with IP address / geo-ip information for a more heuristic approach, though that would be a lot more complex to implement and likely more fragile.

Related

AWS IoT certificates per device or per group of devices?

I do have a question about the best practice for AWS IoT devices, should I create a certificate per device or should I use one certificate for multiple devices or per device type?
I'm trying to find the best practice but I still not getting any information about it.
Each device should have its own unique certificate. Certificates should be used as a form of unique identity for a device.
While you can setup AWS IoT policy based on the client id, that should not be used to uniquely identify a device. Since the client id can potentially be changed through reversed engineering and changed to be whatever device it wanted to be.
While adding the unique certificate does not prevent tampering with the client id, it does give you the ability to block that single device from connecting.
You should create one certificate for each device and attach a policy to that certificate. One policy can be attached to different certificates.

Would it be possible to store cookies on the cloud?

Would it be possible to store cookies in something like a google account when browsing using google chrome(just an example)? Wouldn't this make some aspects of searching the web much safer? Why are we still storing cookies on the device?
The article on HTTP cookies contains useful information on their role/purpose in HTTP.
A cookie .. is a small piece of data sent from a website and stored in a user's web browser while the user is browsing that website. Every time the user loads the website, the browser sends the cookie back to the server to notify the website of the user's previous activity. Cookies were designed to be a reliable mechanism for websites to remember stateful information [between otherwise stateless HTTP requests] ..
In particular, cookies are only/primarily useful as they are because they are stored on the device and because they are sent with the appropriate requests. Thus the entire concept of "storing cookies on the cloud" is unrelated to the primary benefit/use of cookies in the first place!
However, cookies are generally to be considered insecure and should not be used to store sensitive information - this is why cookies are often coupled with sessions and other server-side data access mechanisms which [securely] store information on the server.

How do people handle authentication for RESTful api's (technology agnostic)

i'm looking at building some mobile applications. Therefore, these apps will 'talk' to my server via JSON and via REST (eg. put, post, etc).
If I want to make sure a client phone app is trying to do something that requires some 'permission', how to people handle this?
For example:
Our website sells things -> tv's, car's, dresses, etc. The api will
allow people to browse the shop and purchase items. To buy, you need
to be 'logged in'. I need to make sure that the person who is using
their mobile phone, is really them.
How can this be done?
I've had a look at how twitter does it with their OAuth .. and it looks like they have a number of values in a REQUEST HEADER? If so (and I sorta like this approach), is it possible that I can use another 3rd party as the website to store the username / password (eg. twitter or Facebook are the OAuth providers) .. and all I do is somehow retrieve the custom header data .. and make sure it exists in my db .. else .. get them to authenticate with their OAuth provider?
Or is there another way?
PS. I really don't like the idea of having an API key - I feel that it can be too easily handed to another person, to use (which we can't take the risk).
Our website sells things -> tv's, car's, dresses, etc. The api will
allow people to browse the shop and purchase items. To buy, you need
to be 'logged in'. I need to make sure that the person who is using
their mobile phone, is really them.
If this really is a requirement then you need to store user identities in your system. The most popular form of identity tracking is via username and password.
I've had a look at how twitter does it with their OAuth .. and it
looks like they have a number of values in a REQUEST HEADER? If so
(and I sorta like this approach), is it possible that I can use
another 3rd party as the website to store the username / password (eg.
twitter or Facebook are the OAuth providers) .. and all I do is
somehow retrieve the custom header data .. and make sure it exists in
my db .. else .. get them to authenticate with their OAuth provider?
You are confusing two differing technologies here, OpenID and OAuth (don't feel bad, many people get tripped up on this). OpenID allows you to defer identify tracking and authentication to a provider, and then accept these identities in your application, as the acceptor or relying party. OAuth on the other hand allows an application (consumer) to access user data that belongs to another application or system, without compromising that other applications core security. You would stand up OAuth if you wanted third party developers to access your API on behalf of your users (which is not something you have stated you want to do).
For your stated requirements you can definitely take a look at integrating Open ID into your application. There are many libraries available for integration, but since you asked for an agnostic answer I will not list any of them.
Or is there another way?
Of course. You can store user id's in your system and use basic or digest authentication to secure your API. Basic authentication requires only one (easily computed) additional header on your requests:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
If you use either basic or digest authentication then make sure that your API endpoints are protected with SSL, as otherwise user credentials can easily be sniffed over-the-air. You could also fore go user identification and instead effectively authenticate the user at checkout via credit card information, but that's a judgement call.
As RESTful services uses HTTP calls, you could relay on HTTP Basic Authentication for security purposes. It's simple, direct and is already supported for the protocol; and if you wan't an additional security in transport you could use SSL. Well established products like IBM Websphere Process Server use this approach.
The other way is to build your own security framework according to your application needs. For example, if you wan't your service only to be consumed by certain devices, you'll need maybe to send an encoded token as a header over the wire to verify that the request come from an authorized source. Amazon has an interesting way to do this , you can check it here.

Detecting a "unique" anonymous user

It is impossible to identify a user or request as unique since duping is trivial.
However, there are a handful of methods that, combined, can hamper cheating attempts and give a user quasi-unique status.
I know of the following:
IP Address - store the IP address of each visitor in a database of some sort
Can be faked
Multiple computers/users can have the same address
Users with dynamic IP addresses (some ISP issue them)
Cookie tracking - store a cookie per visitor. Visitors that don't have it are considered "unique"
Can be faked
Cookies can be blocked or cleared via browser
Are there more ways to track non-authorized (non-login, non-authentication) website visitors?
There are actually many ways you can detect a "unique" user. Many of these methods are used by our marketing friends. It get's even easier when you have plugins enabled such as Java, Flash etc.
Currently my favorite presentation of cookie based tracking is evercookie (http://samy.pl/evercookie/). It creates a "permanent" cookie via multiple storage mechanisms, the average user is not able to flush, specifically it uses:
Standard HTTP Cookies
Local Shared Objects (Flash Cookies)
Silverlight Isolated Storage
Storing cookies in RGB values of
auto-generated, force-cached PNGs
using HTML5 Canvas tag to read pixels
(cookies) back out
Storing cookies in Web History
Storing cookies in HTTP ETags
Storing cookies in Web cache
window.name caching
Internet Explorer userData storage
HTML5 Session Storage
HTML5 Local Storage
HTML5 Global Storage
HTML5 Database Storage via SQLite
I can't remember the URL, but there is also a site which tells you how "anonymous" you are based on everything it can gather from your web browser: What plugins you have loaded, what version, what language, screensize, ... Then you can leverage the plugins I was talking about earlier (Flash, Java, ...) to find out even more about the user. I'll edit this post when I find the page whcih showed you "how unique you are" or maybe somebody knows »» actually it looks as if every user is in a way unique!
--EDIT--
Found the page I was talking about: Panopticlick - "How Unique and trackable is your browser".
It collects stuff like User Agent, HTTP_ACCEPT headers, Browser Plugins, Time Zone, Screen Size and Depth, System Fonts (via Java?), Cookies...
My result: Your browser fingerprint appears to be unique among the 1,221,154 tested so far.
Panopticlick has a quite refined method for checking for unique users using fingerprinting. Apart from IP-adress and user-agent it used things like timezone, screen resolution, fonts installed on the system and plugins installed in the browser etc, so it comes up with a very distinct ID for each and every user without storing anything in their computers. False negatives (finding two different users with the exact same fingerprint) are very rare.
A problem with that approach is that it can yield some false positive, i.e. it considers the same user to be a new one if they've installed a new font for example. If this is ok or not depends on your application I suppose.
Yes, it's impossible to tell anonymous visitors apart with 100% certainty. The best that you can do is to gather the information that you have, and try to tell as many visitors apart as you can.
There is one more piece of infomration that you can use:
Browser string
It's not unique, but in combination with the other information it increases the resolution.
If you need to tell the visitors apart with 100% certainty, then you need to make them log in.
There is no sure-fire way to achieve this, in my view. Of your options, cookies are the most likely to yield a reasonably realistic number. NATing and proxy servers can mask the IP addresses of a large number of users, and dynamic IP address allocation will confuse the results for a lot of others
Have you considered using e.g Google Analytics or similar? They do unique visitor tracking as part of their service, and they probably have a lot more money to throw at finding heuristic solutions to this problem than you or I. Just a thought!

What are the approaches to restrict the access to a group of machines in a web system?

My bank website has a security feature that let me register the machines that are allowed to make banking transactions. If someone steals my password, he won't be able to transfer my money from his computer. Only my personal computers are allowed to make transcations from my account. So...
What are the approaches to restrict the access to a group of machines in a web system?
In other words, how to identify the computer who made the http request in the web server?
Why not using a clients certificate inside the certificate store of an authorized host or inside a cryptographic token such as smartcard that can be plugged into any desired computer?
Update: You should take into account that uniquely identifying a computer means obtaining something that is at a relative low level, unaccessable to code embeded in an html page (Javascript, not signed applet or activeX), unless you install something in the desired computer (or executing something signed such as an applet or activeX).
One thing that is unique per computer is the MAC address of the Ethernet card, that is almost ubiquitous on every rather modern (and not so modern) computer. However that couldn't be secure enough since many cards allow changing its MAC address.
Pentium III used to have an unique serial number inside CPU, that could fit perfect for your use. The downside is that no newer CPUs come with such a thing due to privacy concerns from most users.
You could also combine many elements of the computer such as CPU id (model, speed, etc.), motherboard model, hard disk space, memory installed and so on. I think Windows XP used to gather such type of information to feed a hash to uniquely identify a computer for activation purposes.
Update 2: Hard disks also come with serial numbers that can be retrieved by software. Here is an example of how to get it for activation purposes (your case). However it will work if sb takes the HD to another computer. Nonetheless you can still combine it with more unique data from computer (such as MAC address as I said before). I would also add a unique key generated for a user and kept in a database of your own would (that could be retrieved online from a server) along with the rest to feed a hash function that identifies the system.
Did you actually install something?
Over and above what Mark Brittingham mentions about IP addresses, I suppose some kind of hash code that is known only to your bank's computer and your computer(s) would work, provided you installed something. However, if you don't have a very strong password to begin with, what would stop someone from "registering" their computer to steal money from you?
I would guess your bank was doing it by using a trusted applet - my bank used to have a similar approach (honestly I thought it was a bit of a hassle - now they're using a calculator-like code generator instead). The trusted applet has access to your file system, so it can write some sort of identifier to a file on your system and retrieve this later.
A tutorial on using trusted applets.
I'm thinking about using Gears to store locally a hash-something to flag that the computer is registered.
If you are looking for the IP address of the computer that makes an account-creation request, you can easily pull that from the Request. In ASP.NET, you'd use:
string IPAddress = Request.UserHostAddress;
You could then store that with the account record and only accept logins for that account from that IP address. The problem, of course, is that this will not work for a public site at all. Most people come through an ISP that assigns IP addresses dynamically. Even with an always-on internet connection, the ISP will occasionally drop and re-open the connection, resulting in a change of IP address.
Anyway, is this what you are looking for?
Update: if you are looking to register a specific computer, have you considered using cookies? The drawback, of course, is that someone may clear their cookies and thus "unregister" their computer. The problem is, the web only has so much access to your computer (not much) so there is no fool-proof way to "register" a computer. Even if you install an ActiveX control, they could uninstall or delete it (although this is more persistent than a cookie). In the end, you'll always have to provide the end-user with some method for re-registering. And, if you do that, then you might as well have then log in anyway.