Identifying a device accessing an html page - security

The goal:
Limit access to authorized devices who access my HTML5(.html) webapp.
Here's the dilemma:
I have an HTML5 Offline app(.html) that will load all of its resources from a web accessible URL. I want to restrict access to specified devices.
The problem:
Identifying the device. Since .html pages cannot retrieve the mac
address of the device, and if the user could specify the mac address
it could easily be forged.
Since all of the devices will be the same(iPads). User-Agent would not allow me to uniquely identify the device and it could always be faked.
Is there anyway to identify a device by a unique value within Webkit/Safari that can not be forged easily? Mac address would be the ideal value to get, but since this is not possible I am looking for any other ideas that would help identify a device uniquely.
In a perfect world, the device would load the webapp, the webapp would make an ajax request to the CMS to validate the unique identifier of the device and return the result.
Any ideas or thoughts are appreciated. Thanks!

Your best solution here would be to deploy mutually-authenticated SSL between your client tablets and your server. You can use self-signed certificates here so you don't need to buy any from a CA. This will ensure that your server only accepts requests from tablets that have the client-side certificate (configure your server to only accept the self-signed client certificates deployed on your tablets for client authentication).

This would have to be done on the server side. The web client (browser) sends a request to the server with it's details. Now you could do it with javascipt
var browser = navigator.appName;
if (browser == "bad") window.location = "http://example.com";
but the device has to load and execute the code.
The best way would be to use PHP
$browser = $_SERVER['HTTP_USER_AGENT'];
if ($browser == "bad") header ("Location: http://example.com");
but either way you do it it is always possible to give false details since you supply the information in the request.

Related

How can I secure my desktop app calling my API?

My desktop app is used by customers. A customer is a user with a License Key AND his computer's MAC address. The desktop application can only be used on ONE instance.
So when a user buys a license and registers it (meaning he downloaded, opened the desktop app, entered and submitted his license key), I will first retrieve his MAC address and then do a POST request to my API, /user with parameters in that way {license-key: "license_here", mac-address: "mac_here"} so these are saved into my database.
Now, how should I do to secure the API calls in the desktop app, once the user is registered?
Let's say a user wants to access his setting tab, should I provide {license-key: "license_here", mac-address: "mac_here"} as parameters to the GET request and check if it matches his License Key and MAC address in my database, and if it does, display all his settings retrieved from the database on the setting tab?
Or is there a more secure way to do that?
Another way I thought would be for example to hash the license key and the MAC address, concat them and use that an authentication token that I would use for each request.
I am using an API instead of saving locally because I will create a mobile app once I am done with the desktop app, and I will need to share information between both apps.
Using NodeJS with Express and MongoDB/Mongoose.
What you are doing is attempting to authenticate the computer using some data/knowledge that only it has (its MAC and licence key). This is easy to get around as an unlicensed computer can spoof the data and fool you into thinking the request is coming from an licensed computer. If you only transmit the license/MAC data then its possible for any other computer with the knowledge to also impersonate a licensed computer just by intercepting a single request - all the info required to impersonate is contained within the request.
You can't enforce uniqueness of a computer without specialised hardware. This usually takes the form of a dedicated microchip that contains a key or certificate. The data cannot be read from the chip, but the chip can be used to create a digital signature.
Without dedicated hardware the best you can do is to use a unique license key per computer and require all requests to be signed using this key. This relies on the key being private (the signature is sent with the message, not the key itself) and is no guarantee as you don't control the client computer.
Edit - How this works:
Issue a license key to each client. On your server, record each key you issue against the MAC address of the computer it is assigned to. You should probably collect the MAC address at the time of issuing the licence. Do not get clients to 'register' their license. Clients must use the key to sign each request they send and include the signature and MAC in each request. At the server you validate each incoming request by looking up the key using the MAC address and recreating the signature yourself. If the signature matches the one supplied by the client then you know its genuine. Remember - this is still not foolproof! I can buy one license from you and install it on any number of computers so long as I get them all to fake the approved MAC address. I can also give my key to my friends and have them fake the MAC address too.

ASP.NET web api: detect access from new device

I have asp.net web api used by mobile app. In facebook I see notifications like "access to your account from new device". I want to implement the same. Device could be connected to different wi-fi or 3G so to use ip addrress is not good. How to define access from new device and remember it for future in "trusted devices"?
You could look at a combination of pieces of data to uniquely identify see EFF's website on browser fingerprinting.
But the common approach is to set a cookie and check if it is present in future visits.
You need a unique identifier for each device.
In case of a computer it could be a mac address, if it's a mobile device they each have a unique identifier you could send together with the request.
You would then keep a list of these IDs on the API side and every time a request comes in, just check if that ID is in the list you already have. If not then there it is .. new device.
Here is another discussion which could be relevant to your scenario : What is a good unique PC identifier?

Detect a device from within a browser

Several platforms offer security mechanisms to identify if a user ever logged in from a certain device. If you login from a computer you never did they'll ask you special questions on login. How do they recognize a device? Is this only be geo localization (which would not cover multiple devices in the same region, would it?). Or only with cookies which would cause trouble on cookie cleanup.
As far as I know, cookies is really the only way you can do this. The server stores whatever information it can about your device it can get from the browser in a cookie. By geo-location I assume you mean the location of the IP address.
The ones I've seen do this are all based on cookies and do cause trouble if users delete their cookies.
Doing this by IP address would cause headaches for anyone behind a web-proxy or shared connection. It would also be painful for mobile users in transit where the gateway is changing based on cell tower connections. Geolocation would also present problems for mobile users in transit.

How does web browsers transfer Passwords to origin servers?

My question is simple regarding password security..
As a web application developer using PHP for example, I may design a html form that accepts a username and password and post them to the webserver using the POST method..
My question is:
1- When a user enters a password for this form on a web browser, does this web browser send the password over the network as plaintext and thus insecurely?
2-isn't it possible that the web browser saves all passwords and sends them to the third party that design the web browser?
Thank you in advance
Yes, unless you're using https, which encrypts everything sent between the server and the client.
Sure, but you could use a network sniffer to verify that the browser sends no information to third party servers.
It's sent unencrypted (though possibly obfuscated) if you're using HTTP, or encrypted if you're using HTTPS.
Any mainstream web browser won't do that, no. It would be discovered within seconds of the browser being released. However, it's possible for such a leak to occur by other means, for example:
o A rogue browser plugin
o A rogue proxy on the user's network (if you're using HTTP)
o A keylogger on the user's machine

pass secure information from one server to another

The situation is this:
A payment is made to one server, and on completion, it must notify another server securely. What I am trying to do is actually quite similar to a notify_url of a payment service. I.E. paypal receives a payment, and then notifies the origin through a long URL.
How does one verify the data being passed. Any useful libraries? Any links to get me started?
Thanks!
HMAC is a good way to ensure that the URL has not been generated by an unauthorized party or tampered with in any way. Here is a simple tutorial.
If the URL (or the content it returns) contains any sensitive information, then you'll also want to make sure that the recipient server is SSL enabled.
And for a further layer of security, you could hard-code the recipient server to reject any connections that aren't from the IP address(es) of your known sender(s).

Resources