I am thinking of a very simple log in system that doesn't require a login, but instead a system with an id and store it in a database. Then when the user comes back to the website he gets matched with his unique ID and logged-in in that way.
I am trying to do this with php as much as possible, initially I wanted to do it by using the IP address but as some people pointed out, places such as campuses share the same IP for many, many users.
So is there any way to uniquely identify each computer without using cookies, sessions or anything else that is client-side. Preferably with php.
No it is completely impossible to do what you are asking. The only theoretical way would be, as you say - the MAC address but it is not sent in web requests.
Related
I want to give a "like" option on my page for non-logged users.
The simpliest thing would be to detect user IP ( e.g. by $_SERVER['REMOTE_ADDR']).
More sophisticated would be detecting user's agent (e.g. by $_SERVER['HTTP_USER_AGENT']).
But I want to give like-posibility for "each PC in family" (real-life family) - this could also mean they all have not only the same IP, not only the same browser but also the same browser-version...
So how would I determinate whether it is a different PC? (without using cookies/session)
I want to store one "like" per PC and since cookies can be cleared I didn't want to use them :)
I wanted to abstract my particular interest from the whole problematics - so I did.
However you should never trust user input (as David pointed out) - so do not base your final like-count on just that ! At least put a likes/per IP limit and combine it with cookies/session.
Your only option to do this outside the simple methods of using cookies, logins, etc. is to do browser fingerprinting. This technique involves gather a variety of information that the browser outputs to the server/webpage and making a hash of it to create a unique ID for that client. It has a remarkably high accuracy and would work fairly well under the circumstances you are describing.
It is based on the idea that "no two browsers are exactly the same". In other words, you look at screen resolution, user agent strings, active plugins, etc. and create a "fingerprint" of those settings. There is almost always going to be a variance in some way.
There are available libraries that can help get you started. Here is one that is very easy to implement and understand... https://github.com/Valve/fingerprintjs
You can use sessions without using cookies. When the user logs in, they get a token, and this token is appended to every URL they visit. (In PHP you can see this if you disable cookies in the browser, you will get "PHPSESSIONID" in the URL). So, if you make users log in before voting / liking / whatever, then you can achieve this using sessions but not cookies.
If you are talking about public users without a login mechanism, then there really isn't any way to achieve this, unless you set a cookie recording the fact that this browser has voted.
Note however that not only can cookies be deleted, but it won't actually achieve what you want unless everyone in the family uses a different browser or has a separate login on their operating system. Otherwise they are effectively all the same user as far as you can tell. Also people can use multiple browsers so one person could vote / like more than once anyway.
Detecting the User Agent can easily be spoofed; so it isnt a reliable way. The best way to do this is sessions or cookies. Why do you not wish to use them?
Short answer: you can't.
Remember, each request to a web server is a new event. Cookies are the only way to persist data between calls. So if you rule them out you really can't differentiate them. This is a major reason why Google puts long life cookies on their site.
Can cookies be deleted? Sure. But they're really the only option you have.
You cannot give a single identity to a PC.
Cookies can be cleared.
User logins can be done from different computers.
$ip.$http_user_agent will not work.
User may restart the modem and ISP might assign a new IP.
Or use a different browser to change $http_user_agent.
Or another system on a LAN might have the same $http_user_agent.
What is the significance of giving one "like" per PC (provided you are able to even identify a PC correctly)?
What if two different users with different tastes use the same PC?
I am making a script that show popup only one time , then it will never show again on that device..
How is it possible to do this?
I have already tried by using cookies, but these can be deleted by the user and so the effect is limited.
Another question is what is wholly unique per device, IP Address or MAC Address?
The only way is a cookie. There's nothing 100% uniquely identifiable about a machine that you have access to in an HTTP request. Yes, cookies may be deleted by the user. This is deliberate, live with it.
The 2 options that are most obvious are either Cookies or a flag on an Account (if your users are authenticated).
Even though you've mentioned that cookies can be deleted, it's still a reliable form of saying "I have done something for this client before". If the user deletes the cookies then there's a high chance they know what they're doing, and should be expecting to have to repeat tasks (such as logging into other websites too).
If your users are authenticated (namely: they have to login to your site/service), then you can easily store a flag saying that the user has already been shown the notification.
That way is of course more reliable, but relies on authentication. Long story short: You need to take what you can get, and cookies are your best bet to have some form of unique device ID.
Regarding your other question: Nothing is unique in reality. MAC Addresses (which you wouldn't have access to anyway) can be spoofed, and IPs can be shared.
Neither. Millions of Internet devices have 192.168.0.2 as their IP. So that's not unique. And MAC addresses aren't Internet things at all, they're Ethernet things.
If you explain your outer problem in more detail, there's probably a solution. But it sounds strangely bogus from what you've said already. The same person on two different devices should get the popup twice? But with two people on the same machine, the first person should get it only? It's hard to imagine a use case where you should go out of your way to ensure that.
This is a very broad question; I'm just looking for the best way to do it.
I want to be able to differentiate a unique user. I need to be able to track when a user visits a specific page.
Here are the problems that I and other people have encountered :
Using an IP address is not effective because there might be many computers on an IP address
Using COOKIES encounters a problem if the user clears his/her cookies in a given period of time.
Using SESSIONS encounters a problem if the session expires.
I am considering a combination of all three, but I'm still pretty sure this will not catch all the exceptions. I need a system similiar to the way Youtube tracks views on their videos.
Does anyone have any other ideas to this? (Aside from implementing a user system)
Without using cookies/requiring users to login to identify themselves - determining whether they are "unique" or not will be nearly impossible. There are a few methods to help, but neither are guaranteed:
You can use PHP Sessions - without requiring an actual "user management system".
session_start();
$id = session_id();
The upside to this is, you'll be able to track the current user as long as their session remains active.
The downside is, you won't be able to determine if the "new user" is unique or not if it's an old user who's session has cleared (much like if the user has cleared their cookies).
An alternative, but also along the same lines as using just the IP address, is to attempt a best-possible fingerprinting algorithm using different variables from the $_SERVER environment info:
$userFingerprint = $_SERVER['REMOTE_ADDR'] . ':' . $_SERVER['HTTP_USER_AGENT'] . ':' . $_SERVER['HTTP_ACCEPT']; // plus any others you might find helpful
The upside to this is, there may be enough data to differentiate between users on the same network.
The obvious downside is, there may not be enough data to differentiate between users on the same network.
I think, there isn't any absolute way to do this. Users can change ip address, delete or change cookies etc., because everthing is on their hand.
But according to system (poll, counter) which you are planning, you can develop a way to determine unique user. For example to develop a poll system, you can insert ip, http_user_agent to database and also to increase quality you can set some cookie.
One other way may be to create a table in your database capturing the following data:
IP address
Operating system/ browser etc. (any other info that would
be specific to that user)
Then, you could narrow it down and say, "A user at this particular IP address using this particular OS on this particular browser downloaded this image at this particular time."
Is that what you want to achieve?
I need to make sure that every users accessing my web application can do that from one machine only, so 100 users would mean 100 machines. What would be the best solution? Is detecting and storing IP during first login good idea? I think IP might change even during lifetime of the session is that right? I was also thinking of storing cookie when user first logs in. Then assigning these cookie to the user, same as I do with password and username already, and every time when accessing application checking for presence of that cookie.
Please let me know what in your opinion would be the best solution. My backend is php/mysql if that matters.
EDIT: I need to clarify... This is in addition to normal session management. I need to restrict users to be able to login to web application from one specific machine only. So if user originally logged in from his computer at work and I stored its ip/cookie/etc., then client logs out (or even not), goes home and tries to login won't be able to do that. I agree its horrible idea but client insists :)
IP address might change in the case of mobile clients, or clients that switch between wired and wireless networks. Your best bet would probably be to provide a randomly-generated UID to each client when it first connects (if it doesn't already have the cookie). Then you can check that the same username isn't connecting using two different UIDs.
The trick is that you need to make sure to time this UID out, so that if the user goes to another computer they aren't locked out. Perhaps one change to the UID is okay, but they can't go back to a UID that's already been used?
You can limit to a single useragent by issuing the client with a client side SSL certificate created with the keygen element, this gets the browser to generate a key pair, keeping the private key in the user agent, then you receive an SPKAC, which you can use to openssl create a certificate, which you then send back to the user agent, it installs it and it can be used to identify the user in that specific browser only via HTTP+TLS from then on.
Anything else, simply won't work 100% - although you can hack ways that appear to work (until something goes wrong and it doesn't work) :)
Unfortunately, an IP is not machine-specific for multiple reasons:
The IP address could change during the session, with no notice (the user might not even be aware of it)
Most users have dynamic IP, so it most definitely will change at some point
For machines such as a laptop, tablet or cell phone, the IP address is based on the current service provider
All users behind a proxy would appear to you as a single IP, so you still wouldn't be able to detect if they moved from one machine to another
Instead, generate some kind of unique key for the session and track it in combination with the user name. Prevent them from logging in if the same user name is already in another active session. (You'll also want some way to automatically flush these, just in case you lose the session-end event.)
The best solution is already built into the web server depending on which one you are using. That's what the Sessions are for. In ASP.NET/IIS, usually there is a 20minutes per session timeout.
So if a user uses another computer to access your webapplication, then the session timeout will release connection from the machine that is idle.
UPDATE
You might want to consider restricting user by the MAC Address of their machines which are unique.
If it is a very internal application that will be used only inside a company, it might be possible to define an IP range because smaller companies which do not operate worldwide will probably have a certain amount of IPs from their internet access provider.
You could also think about using some info from $_SERVER to restrict users to a combnation of a single web browser (HTTP_USER_AGENT) and a single port (REMOTE_PORT) - as an additional way to differentiate machines.
But all these solutions are bad or worse, it's technically probably not possible to solve this problem (unless you will have guarantees from your client that all machines will keep a static IP in which case it is a trivial if else problem).
Don't do that. Many people will access your website from multiple computers, and they will complain if you block them.
I'm currently in charge of setting up a polling system (using PHP).
Now for it to be as secure and objective as possible, it's important that a visitor can only vote once. I'm thinking of validating the polls by visitor's IP (there can be only one vote from one IP), and maybe throw in a captcha test to be sure that no bots can get in once they've passed the IP validation for some reason.
So there it is, unique-IP validation and captcha. But is this enough ? Is there a possibility that a single user can change his/her IP by using proxies or other ways I don't know of, and vote multiple times with unique IPs ?
Are there better ways to do this ? Preferably without the captcha.
Thanks in advance.
There is absolutely no way to be sure a user has voted once when it's a public voting system, where no login is required.
Checking the IP is not a good idea for several reason. As described in other answers, lots of networks are behind one ip, and users can just use an other pc with different ip and vote again.
OpenId
Use OpenId to identify the user and check if they have already voted.
Register users
Optionally you could allow users to register themselves if they do not have an openid account.
To implement a secure system, where session spoofing, and thus multiple voting, is made difficult read this
You can't create a 100% secure voting system.
If it's based on registration/IP/cookie, the user can create a new user/get an another PC/delete all cookie.
But you can try it with auto prefilter + administrator as postfilter workflow:
Prevent multiple voting with cookie (or IP / browser properties / etc.) filtering automatically.
On an admin view, the administrator can parse and delete votes by hand based on IP or subnet address. This is nor a perfect solution, but with some good query (same votes in the same time intervall from the same IP/subnet) the administrator can easily delete suspicious votes.
One big drawback of this solution is the need of an administrator. But - I think - there is no perfect solution.
Unless you're going to require identity verified by CA, there is no way you can be sure, that each person votes only once. This of course would be total overkill, so the real question is: how to make multiple votes more difficult.
email with verification code. IMHO overkill, but depends on how sure you want to be.
use session to check who voted. Obviously not 100% secure, but will stop 99% of ppl.
use cookie to check who voted. Like above, some ppl will know how do delete cookies.
use POST, ignore GET.
use combination of 2 or 3 of above.
If you're going to use IP for validation, do not use just REMOTE_ADDR, combine with whole X-Forwarded-For. This way you won't block people connecting through same proxy.
Don't go with the way of unique Ip. There are a lot of case scenario where a lot of users have the same ip (i.e. italian isp fastweb, large corporations, etc). Also, if user has dynamic ip it can change it's own ip address every time he likes...
One of the best ways should be using email address and cookies. User will be able to vote multiple times (you can't avoid this), but at least it will take them some time for each vote.
for a similar project i did 2 verifications ...
i placed a cookie and also saved on the server a hash from users ip + user agent.
this seemed to be pretty effective since even if there are more people that use the same IP the hash with user agent will be different most of the times since it differs for same browser depending on the operating system and other extensions installed.
There is no fool proof way for preventing multi votes. Checking cookie is anothr option.
Regarding Validatin the ip address. What if the user is from a net work which is used by many users?