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.
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 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.
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?
Two types of users visit my website: registered users and guests. Registered users are tracked and retained by PHP session, cookies and individual logins. Guests I find trickier to manage so I give little to no authority to contribute content.
I want to open up editing for users (registered or not) to save favourites, shopping carts, vote in polls, moderate, tag, upload and comment. At the same time, protect the data from other non-registered users.
What are some options or best practices to determine a unique visitor from another and some security measures to consider when allowing them to contribute more? Should I work around their security/restriction settings to provide contribution service or should I expect them to meet in the middle and relax some of their settings to allow cookies etc?
IP Address - The IP is an option but only temporary. It can change for a user reconnecting to their Internet with a different IP, and for that matter another user may eventually share the same IP. IP can also be anonymous, shared or misleading.
PHP Sessions - OK for a session (and if enabled) but lost on closing the browser.
Cookies - Can store session data but is easily (and often) disabled from the client-side.
Header data - combining known details of he user might at least group users - ISP, browser, operating system, referring website etc.
Edit: I'm still having trouble getting my head around all the the key factors involved... we set up a cookie for a guest. Attach a bunch of edits and user history to that session. If the cookie is removed, the data floats around attached to nothing and the user loses their data. Or if the user logs in, the guest and user data should be merged...
I think cookies would probably be the best option here as it's the only way you are going to be 100% sure requests are unique. Of course, you could possibly add a mix: if cookies are disabled you might be able to try other options of identification such as the IP address method, but that could make it overly-complex.
As you say, IP address is liable to change and in some organizations there may be a group of proxy servers setup which make requests originate from different IPs. Of course, you could check X_FORWARDED_FOR, but they are still liable to change.
Header data is probably going to prove difficult to get good results on I think. If you've got an organization that has the same browser, OS, IP it is going to show people as being the same. Even people not in the same organization may still appear similar (i.e AOL users who get their traffic usually routed through proxy servers, the majority will probably be using the 'AOL browser' that gets shipped with it giving similar headers).
Out of those two options, the IP one is going to be easy to implement but obviously there are the problems I outlined. Checking for unique data in the headers will prove to be absolute pain I think.
Obviously as you say, sessions are lost on closing the browser, and it appears you want the system to behave as if they were a registered user so cookies seem a more obvious choice (especially as you want the 'favourites' to be persistent).
I would just go with sessions.
Your users could change IP addresses (prone to mixup behind NATs and proxies), modify/delete cookies (certainly possible), or change their header (easily through switching browsers).
There is no secure way of identifying a guest if they do not want to be identified. Just go with the standard: cookies/sessions.
You should use sessions.
Sessions id are stored in a cookie (or for users who doesn't accept cookie, stored in the url with the PHPSID argument)
They won't be erased when the user will close his browser, it just depends on how you set your session/cookies options.
You can set up the timelife of a session to whatever you want, so don't bother with this.
You should also tell to your user about this (enable cookie)
Concerning the data which could be merged when log in, it's your job, to merge it in a proper way, or even ask the user if the option should be saved or not.
You could use a combination of all of the identifying points that you can find, that are not likely to change, and are likely to be unique - looking at panopticlick you can gather a bunch of data such as installed fonts and browser plugins. You could take those kinds of more unique data points and hash them to give you an id, and then compare it against the less unique data like useragents and ip addresses.
But honestly, that's super complicated and sneaky. Use cookies/session. If the user doesn't want to enable cookies then they don't want all your anonymous tracking for a reason, and you should honor their decision.