I'm building a PHP webpage which has a Button to download an image. I want to restrict unsigned user to download this image 3 times only.
I don't want to use neither Session nor Cookies because the user can delete his cookies!
I want to use IP, so I used the $_SERVER global variable but the problem here is the IP Address is changeable. It's dynamic and change every period of time.
So What should I do?
Not all IPs are dynamic, this depends on the ISP. Your problem is identifying the user uniquely, which is impossible to do without requiring users to log in. No matter what you use, IPs, cookies, sessions, client side scripts to do browser fingerprinting or store tokens in the localStorage, a skilled used will always manage to get over your protections.
You can only make it difficult for the users:
run a client side script to create browser finger print - https://github.com/Valve/fingerprintjs2 - and send it to the server to help you identify the user
generate a server-side token and send it to the client and store it in the localStorage and send it back to the server
store the IP of the user in the DB
use session / cookies to add an extra layer of security
use an hidden iframe to load code from a different domain you own and add extra cookies from there (sometimes users don't delete all the cookies, just those for your site)
put captchas before the user can download an image so that you're not scrapped by bots
Using a combination of all the above will make it annoying for an user to download pictures from your site without creating an user account, but not impossible.
Related
Building a web application that is 90% API-based, meaning it will be hosted on the client's website (eg clientdomain.com). When API calls are made, we are creating and storing a session ID on the client's domain, and we store all the stats on their activity while a visitor browses their site.
But there's one part of our application that is hosted on our servers, because it has to be secure (eg client.ourdomain.com). Visitors will click a link from the client's website to ours.
What's the best way to somehow tell the application on our domain that this is an active session with session id XXXXXXX? I've thought of a few options:
Check sessions table for IP and timestamp within a certain range. Obviously this would not be a good option because some large groups and organizations use the same IP.
Pass the session ID as a GET variable, downside is these links may be shared or saved for later use.
Pass as POST var using a form button
Use some kind of redirect variable dynamically created that is only good for a small time frame (i.e. 10 or 30 minutes) and then deleted
Am I missing a possible solution?
Our ultimate goal is to track a visitor through goal completion so we can show conversion rate, bounce rate, etc. To do that we absolutely have to match up a visitor from clientdomain.com to client.ourdomain.com.
Thanks in advance!
Your first option is the answer, SessionID + IP = Unique.
User A and User B may have the same IP but their session id is different.
Fifth:
go
redirect-to-secure.php:
header('Location: http://client.ourdomain.com/?clientSession=' . session_id());
On client.ourdomain.com, if you detect clientSession GET param, save it to session and redirect to page without clientSession. This way browser won't remember this url.
In my login code on my website, if the password & username are correct, I set a cookie to keep the user logged in.
I just heard from a user that he doesn't accept cookies automatically through his browser, and that that prevents him from logging in. That rhe cookie is not set.
Is there an easy way to counter that?
Tell me if you need the code I use.
It is possible to get this to work but often a real pain if you're using complex javascript/ajax.
In short, instead of storing the session id in a cookie, you embed it at the end of every link.
so
http://example.com/somepage.php
becomes
http://example.com/somepage.php?SessionId=ABC123
Unfortunately, while PHP can do this for you in some cases, it doesn't help with links you build yourself in javascript - and it only takes clicking a single link without the id to effectively log the user out
See this page for more information
As mentioned by Quentin in the comments, if you're not using a cookie to identify the browser which created the session, it's possible that sharing a link would share the session. This could be mitigated but not prevented by checking IP address/user agent but this would likely fail in large corporate environments with NAT and standard browsers
Is it possible to have the same session be active across multiple open windows in a php app?
I want to have SOME of the convenience of the dreaded "remember me" checkbox type system without the same amount of risk to the user's data.
The specific use case I have run into is this: When a user receives a "friend request", an e-mail is sent to them with a link that contains a random hash and their username in the url. Say the person is already logged in to my service in one window and is checking their mail for the confirmation e-mail in another. They click the link in the confirmation e-mail and it launches a third window which initiates a GET request to the relevant confirmation page. I'd like to make it so that if the user is already logged in to the service in another window and the hash and username match those stored in the "requests" table of my database, clicking the link instantly confirms the friend. However, if they are not already logged in in another window, they are then forced to log in to confirm the friend request.
Currently if a person is logged in in another window, clicking the link launches a third window and the person must log in again regardless of whether they have another open session.
Is this functionality possible without using cookies to maintain a persistent login?
Update: This question demonstrates my own lack of understanding regarding how sessions work. The user's session IS normally preserved across concurrently open browser windows by default. The issue, as was addressed in the answer I accepted was that I had one window open with www.example.com as the URL and one with example.com as the URL, in which case a different session is created in the second window rather than continuing the session started in the first window.
If you use cookie-based sessions, the session is already maintained between windows (of the same browser executable).
The session ID is the only client-side stored token in this case, and browsers don't generally segregate cookies between different windows.
You may have an issue in that they're visiting your web site via two different domain names (www.example.com vs example.com vs www.example.org, or the like), but fundamentally there is no problem unless you try to use GET-passed session IDs.
You will technically "use cookies" - but the cookies only hold the session ID, not the session contents. If that is anathema to you, you could store the session ID using the HTML5 LocalData API, or with a Flash object, or a Java applet, or whatever...
I strongly advise against attempting to identify the clients a posteriori via their IP address or browser characteristics. Just have them store a token, and use that to determine who they are.
A typical login system has sessions and cookies . Cookies are only set if the users wants to be remembered to avoid input hes data again from that spesific browser and nothing else.
Session live while you are loggen but the will be destroyde after you close the window thus prompting for a login again.
While saving cookies to a users browser it is vital that you encrypte their data .also instead of the password save a cookie with a refrensnumber (ID) and not their password.
What is the best way for storing users IDs or usernames so they will not have to login every time?
I want to forward user to the members page if the stored ID or username is compared with the one stored in database.
Is is safe to do it using cookies and how can I do that?
Don't store their username or password in a cookie. Always assume that everyone on the internet can see every cookie on a person's computer. What you should do instead is save the session_id and the IP address they accessed from to your MySQL table, then save the session_id to a cookie. Most browsers will clear session variables when you close the window, but they will not clear cookies. Therefore you first check the session (are they currently logged in), and if they're not logged in then you check the cookie (were the logged in before, and more importantly- was it from this IP address?)
Of course if they have a session_id but they're not at the proper IP address, make them log in. They could just have an ISP with dynamic IPs, or they could have been listening to network traffic and they're trying to get into the admin user without a password.
This feature should be optional to let people log in from internet-cafe and such, not leaving their data open to everyone.
Yes. a cookie is the only possible way to mark a browser.
You have to store some uniqie and unpredictable value there. Generate some hash out of user's data, store it in the database along with other user data and set it as a cookie
The safest way is to require a valid SSL certificate from the browser, and validate the user-agents certificate server sided. However, in any browser I've seen installing such certificates is a big enough pain & hurdle for users that it's probably not suited for a public website. It can however sometimes be seen in intranets.
I just wrote this solution for anyone else who is interested.
http://rabbie.id.au/my-elegant-remember-me-solution-using-php-mysql-and-cookies/
With my sites, I use a custom written Session class. This stores a sess_id and sess_hash in a cookie, which is unique for the current user. An IP address is also stored in the database, and checked against the current IP to verify it is the same computer, but that is not the main authentication mechanism. Data is then stored, serialised and base64'd in the database. I would advise against using PHP Sessions, because they can be accessed by any user with the ID. Someone posting a link to something with the PHPSESSID in it, can, for example, let them log into their account.
Problem: A download link should be displayed in a user's home page.
That download link should ONLY be accessible if the user logged in.
But the real problem is that the user's home page and the download link are on separate web servers.
Is there a way I can send a token with the download link and validate it there?
users server = serverA.com
your server = serverB.org
if i understand it right, the problem is, that the user is only logged in on server A, but not on server B, and there's no way to share the session state (e.g. session handling over a database)?
from the top of my head, i can think of one option:
server B simply asks server A
means: link on serverA contains the users session id*. serverB then asks server A if the session is valid.
you can't do it without communication between those two servers.
* note: instead of the session-id it would be better to use a random token. session ids should not be private.
that won't stop your users to share the url, so if they want someone else to download the file, they can simply pass the url around. on the other hand, a malicious user could also do this with his session-id.
You could make the download link submit a form with the user info to the target server. There are security implications in doing that, because the login info would appear in the source of the page as values for hidden form fields, so perhaps that not the way you'd like to go.
A second option would be to store the session info in a database, and then simply pass the session key to the new server. This would require the second server be able to contact the first server's database and run a query on it. Setting up a username with permissions to login from that server for read access should be sufficient to do that without opening many security holes.
Finally, you could set up a web service on the first server that would return a yes/no answer when given a username, verifying the logged in status of the user. The receiving link on the second server would then take the username and verify the logged in status before building the response.
If the user clicks the link, he is going from his server to your server.
And if he is logged in on your server, then you can do whatever checks you need since he is trying to access the file on your server. Even though the link is displayed on some other server.
That is if you are using sessions to keep the user logged in, it should be enough in the download code to start the session with session_start() and the user should get logged in session he has already.