Identify different user machines on web server side - webserver

I've done some reading on User-agent attributes
and even client-side exploits to recover user information.
I want to know if it is possible to legally identify a web client running on a specific computer (not smart phone) as a unique device using the currently available web browsers.

I'd use cookies personally, but if you want to give a computer/browser an ID:
$id = md5($_SERVER['REMOTE_ADDR'].$_SERVER['USER_AGENT']);
This will create a unique md5 sum based off the IP address and user agent, so even using a different browser on the same machine will give you a different ID. You could use this ID to store information in a database or file.
The question doesn't specify a language so I've used PHP for my example, but the principle is the same as with other languages anyway.

Related

Authenticating lots of clients for a REST API

We have a large number of small devices deployed in the wild that communicate with a central server via a REST API. It will send a status update on a regular basis with some sensor data and will also ask the server if there are any software updates that need to be applied. If there are, it will download it etc.
I'd like some way to prevent my server API from being used by unauthorised clients. Here are the solutions that I have and the issues which I anticipate. This question is somewhat open ended but it is mostly a question of best practices for, what I think is, a common situation.
Keep a single username/password on the server and then use basic auth over https. This is simple but if I change it, I'd have to somehow change the credentials on all of my devices (which number in the low thousands). This is hard to do reliably. There's also a problem with how the devices are going to get the update without first changing their creds.
The second is to create a username/password for every device. Then I can update individual ones and manage them but there's a lot of state on the server and I'm worried about having this much data on the server.
Some kind of automatic key based system whereby the devices can ask for an expirable key and then use that for all transactions. If the key expires or is invalidated, that device can't connect anymore. This would necessitate some kind of id for the device which I'm not sure how to handle.
So, how would I do this?
Update
In our setup, we have assigned hostnames for each of the devices we're going to deploy created beforehand. Once the devices switch on, they will contact the server with their hostnames and thereby register themselves. The MAC address and other information is passed as part of the initial registration handshake.
So, the "unique identifer" which was mentioned in the answer (and comment) by Noksi is the hostname. This can be easily spoofed (since the hostnames have a pattern). However, when the devices first come online, we can get the mac and, after that, only refresh the token if the request comes from the same mac. This opens up the possibility of a fake registration happening the first time though.
If there is some way to uniquely identify each device (similar to a MAC address) then that would be the key. Keep a registry of the devices and each device would register with the server. the server would provide the device with a token and associate it (the token) with the registered device. the device uses that token to make requests. tokens can be made to expire and renewed as needed or can be black listed if needed. This seems to be similar to option 3 in the proposed options.

How to share Presence among Resources?

I'm developing a cross-platform application and which incoorperates XMPP (ejabberd). How can I share presence among resources?
Please consider the following scenario:
User A is logged onto three devices: PC, Android and iOS. User A, using Android, sets his presence to 'away'. How can I set (synchronise) the other resources to 'away' (and send out presence stanzas)?
I'm looking to solve this problem using the XMPP protocol / ejabberd server; not by adding logic to the clients.
You do not really need to synchronise presence among your resource. What you need is a display rules from your other clients.
For example, if a user has three different resources you may decide:
To display the most available resource of the three.
To display the most recent one.
To display the one with the highest priority.
So, you do not net to synchronize them as you will lose precision. Simply define your presence display rules, based on the goal of your client application.

How to prevent connection to the server without my client application?

A client asked me to do a back-end server for its iPhone application and want only users who bought the application to be able to call the server.
The problem is that he doesn't want to add a login system to the application, so that it seems to me there is no completely safe way to prevent someone without his application calls the server.
In any case, even if it can not be completely prevented, it would be sufficient to make it difficult to access servers without the application.
What is the best way to achieve this? Again, I do not need to fully protect the connection, there is no transit of sensitive information, I just want to make things a little more complicated for people who want to take advantage of server without paying the application.
The idea that seems most simple is to encrypt the data with a key stored within the client and known to the server, so that the message can be decrypted only decompiling the code and finding the key (of course instead of a key you could put a list of keys, which change every 6/12/24 hours).
Could this be a reasonable solution?
This will never be possible. Welcome to the nature of the client-server architecture. You can never trust the client. Just make sure the functionality you are exposing is safe.
well if its a paid app you could release the app for free with all the functionally locked down until a user does a in app purchase and then you could verify the receipt on your server therefore proving that the device is a iOS Device?
sharing a key between the client and the server seems to be a good way to go. But instead of depending on the stored keys only, try combining them with a Unique identifier, such as UUID and send it to server both with the combined key, and the UUID itself.
At that point users UUID will be his identifier (username) and the combined key will be his token (password). And this will be a login-like mechanism.
An SSL connection is not enought to prevent other people from getting the URL for the requests? Or even better using an SSL connection with a basic auth?

Is there some way to determine the client to my HTTP SOAP API currently?

I know that user agent can be faked easily when connecting through HTTP. I want to ensure access to my SOAP API only from iPhone devices. We don't know how many users will be using this when it is released but it might be a lot and we can't handle traffic from outside of the devices. Any other means to prevent this?
It's not clear to me why limiting just to iPhones would be the way to go since I guess what you're really worried about is volume per user on the API (iPhone or not) and number of users. Spoofing the client is pretty easy so a better way to would be either to issue keys/ids on signup and then limit volume on each key or by IP address. Using keys also means you'll have a better ID on your users which might be useful in the long run. IP addresses could be problematic with mobile clients but at least you can do some basic load limiting.
Unless you control both sides, there's no way to determine the type of the other party reliably over HTTP.
No. (Outside of asking them if they're on an iPhone of course.)

How to create an SaaS Application?

I don't know how else to say it so I'm just going to explain my ideal scenario and hopefully you can explain to me how to implement it...
I'm creating an application with the Zend Framework that will be hosted with DreamHost. The application will be hosted on its own domain (i.e. example-app.com). Basically, a user should be able to sign up, get their own domain sampleuser.example-app.com or example-app.com/sampleuser which points to, what looks like their own instance of the app, which is really a single instance serving up different content based on the url.
Eventually, I want my users to be able to create their own domain (like foobar.com) that points to sampleuser.example-app.com, such that visitors to foobar.com don't notice that the site is really being served up from example-app.com.
I don't know how to do most of that stuff. How does this process work? Do I need to do some funky stuff with Apache or can this be done with a third party host, like DreamHost?
Update: Thanks for the advice! I've decided to bite the bullet and upgrade my hosting plan to utilize wildcard subdomains. It's cheaper than I was expecting! I also found out about domain reseller programs, like opensrs.com, that have their own API. I think using one of these APIs will be the solution to my domain registration issue.
Subdomains are easy. In hosting environements, in most cases, apache is configured to catch all subdomain calls below the main domain. You just need to have a wildcard DNS defined, so *.example-app.com are pointed to IP of your server. Then your website should catch all calls to those subdomain names.
Other domains are hard. They need to be configured as virtual hosts in Apache - see http://httpd.apache.org/docs/1.3/vhosts/name-based.html - that means it will be difficult to automate that, especially in hosting environement - unless your host gives you some API to do just that (easy and more feasible scenario would be to have a distinctive IP assigned to your website, then you can catch all with your Apache - it's probably possible to configure using your hosting control panel or works out of the box - and then just point DNS servers to your IP).
Then, after you have configured your Apache to point all necessary calls to your website, you can differnetiate application partitions per subdomain in this way:
get the host header from HTTP request
have a database table containing all subdomain names you're serving
make a lookup to that database table to determine instance, or user, id and use it later for filtering data / or selecting a database, if you'll go with a "database per application instance" schema.
Good luck :)