I have a mobile website where, as part of my security measures, I want users to "register" their device, so I can limit the number of devices that users can have accessing the site. My thought was, for a "new" device, put them through a two-factor authentication process, and store a server-sent GUID in an httpOnly cookie (over SSL) which will hold the GUID. When the user comes to the site and logs in using their username and password, the server will compare that cookie against their user record in the database, and if it's a match let's them log in.
So my question is: is this a valid/secure use of httpOnly cookies? Does the method that I'm describing for "device registration" make sense?
Thanks!
This would stop casual users from using multiple devices with your service, but it would be easy to circumvent as they could copy the cookie to another device. The HttpOnly flag simply restricts client-side script such as JavaScript from accessing the cookie, it does not prevent the user themselves accessing the cookie or force encryption of it in any way in the cookie jar.
You could make your solution work though with a little bit more engineering: Rolling tokens for each device. By this I mean it would give each client a new device ID on every login, and this mechanism will also invalidate the old one. This would cause a second device with a copy of the original cookie to be no longer able to use your service without separate registration and a count against your device limit.
Also, it might be better to use something other than GUIDs depending on the level of security needed as they are possibly predictable:
How secure are GUIDs in terms of predictability?
Are GUIDs safe for one-time tokens?
Related
I'm making a simple star rating feature in PHP to my site and my general question is, do cookies prevent people from spamming multiple votes?
As far as I know I can store a cookie with javascript and PHP. What's to prevent the spammer from testing the feature, looking at what cookies are saved and then remove/add them in the spam attack script?
A sub question would be, what should I save in the cookie? That the person has already voted? What's to prevent the spammer from automatically delete all cookies before a spam attack?
So far I've got honeypot, secret code calculated by time and some other things and IP blacklisting.
I will try to stay out of captchas and recaptchas.
Here's the fact: At the worst possible case, a user may get an entire new computer to cheat your system. And there's nothing you can do about it. So no matter which client-side protections you have, they can be broken.
Cookies are trivial to reset.
Sessions rely on cookies, hence, trivial to reset.
IP is easy enough to reset (or use a VPN or some other such service), moreover, mobile devices change IPs as you walk down the street.
The only real way is to authenticate your users (i.e. a login system) and only allow for authenticated users to vote.
Note that a Cookie will probably work for 95% of the cases, if you don't care the occasional cheat here and there. If cheating must be prevented at all costs, you need an authentication system.
Looks like you are talking about anonymous / unauthenticated users (guests) - because if it's logged in users you can validate on server-side much more easily (e.g with Zanderwar's answer on sessions).
I'm sure you already know this rule, but in case you don't know:
Don't do security validations on client side - you never know what browser, mobile or client the user is using. It's very easy to strip aside client side validations, spoof REST variables, encode/decode, replay transactions etc on the modern clients. So don't do security validations on clientside. Client side validation should only be used to enhance the user experience, and proper security validation should be done on server side only.
For unauthenticated, anonymous users I would restrict submissions by IP and time. E.g per IP they can only submit once per hour. You will have to record the IP and time on serverside and reject (or just update) submissions that are too frequent.
This is the simplest solution to your problem I can think of.
There is no way to prevent spam with cookies or sessions. Any time you spend on this concept will be entirely wasted.
That doesn't mean that the session control can not be useful but it can not by itself prevent an experienced user from anything.
Voting sites usually rely either on an authentication system or the client's IP and time stamp to limit users.
Using the browser string together with IP would make it harder but you run the risk of preventing multiple people behind the same firewall (same IP) from voting if they have very similar setup (as you could have in an office)
Aside from that login is another option but could be circumvented by creating multiple accounts.
But preventing multiple votes is always a problem unless you have an existing verified identity of the visitor.
It will never get a full protection without using Captcha or any other anti-bot protection as long as you give guests to use this feature.
The closest you can do, is to block by User-Agent + IP if they vote to much in a certain amount of time.
Another thing, you can do is to find a workaround using JWT authentication. It's a nice tool for client side session management.
Also, you can try and implement a CSRF protection. For example, you can create a unique token when loading the page of the vote, and when a user clicks on one of the stars, the system will send this token along with the vote rating.
But, again, there is no a bulletproof solution for your problem.
I'm building a web application that accesses a private API. The API that I'm consuming uses HTTP Basic Authentication over TLS. My client has requested a "remember me" functionality for the web app so that users can maintain persistent authentication on a given device.
My quick-and-dirty solution is to store the Authorization header in localStorage after it has been validated. Of course, given unmitigated access to a user's device, anybody who is worth their weight in salt could copy the auth header from localStorage and decode it to retrieve the user's login/password combo.
Aside from total device compromise, are there any other security implications from storing this type of sensitive data in localStorage? Is localStorage acceptable as a store for sensitive data such as passwords? If not, how would you persist such data on a user's device beyond an individual browser session?
(I wish everybody could just use his or her private key...passwords are so 90s)
EDIT After reading HTML5 localStorage security it seems clear that storage of sensitive data in localStorage in general is a bad idea, but what better option is there for authentication persistence in this case?
I think it's a bad idea to store something related to the login or the password on the user's side.
But once an user has logged in, you can store a random string (a random hash for example) on the user's side and in your database. When the user get back, you can compare the two and if they are identical, you can log in the user. And you can ask the user to enter his password for sensitive actions (change password or login, etc.). So even if the hash is stolen, no one will be able to get the full access to this account.
Edit : this concept is already used with cookies. I've never tested it with localStorage.
From a lot of posts I've seen on the site, logins performed by AJAX or traditional forms are just as secure as one another. (re: Login/session cookies, Ajax and security Ajax login and javascript cookies, is this secure?)
My question(s) is/are:
If I hash the user's password (via client-side/javascript hash
libraries) before I send it to the server, do I increase security from people easedropping?
If I put a form token (one random based, another time based), does that cover CSRF attacks?
Would I have all my bases covered after all this? Would this form be secure?
Actually this could be a major security problem. The reason why passwords are hashed is a means of planning on failure. An attacker might gain access to the data store (sql injection) and then obtain the hash. If you are just logging in with a hash, then the attacker doesn't have to crack the recovered hash in order to gain access to the application.
Replay attacks are also a problem. If I sniff the hash during authentication, whats stopping me from just replaying that request to authenticate?
Protocols that use message digest functions for authentication provide the client with a nonce, which is used as a one time salt. Microsoft's SMB NTLM authentication is a good example, but it has had a lot of problems.
USE SSL, and not just for login. OWASP A9 states that the session id must never be leaked over an insecure channel. After all who cares about the password if you just spill the real authentication credentials a few milliseconds later.
Most people don't implement CSRF protection for login. After all the attacker would have to know the password in the first place, so "session riding" is a moot point.
A slight aside, but in answer to question 3. NO! Also remember that AJAX and standard forms are also just as insecure as one another.
Implementing secure authentication is hard. Unless you are doing it as an academic exercise, i would strongly recommend using the library provided by your framework, if you are lucky enough to have a good one.
You will also need to consider things such as the following, and more.
Implement a suitably random and unguessable session id for use in the session cookie.
Do not allow the session id to be forced.
When permissions or credentials are changed (e.g. because the user has now logged in or out) then
immediately invalidate the session and start a fresh one.
Provide a logout feature, and be sure to invalidate the session upon logout.
Set the cookie to HttpOnly -Preferably require HTTPS and alo set the cookie to secure only.
Consider restricting the session validity to include checking some other information that helps to match the user e.g. user-agent.
Always expire sessions after non-use and do not implement "keep me logged in" by reconnecting the user to their old http session.
Ensure 2 sessions can't have the same session id at the same time
Ensure that all session data is destroyed when a session is invalidated. A new user coming along, may just happen to get assigned a session id that has been used previously. This new session must not have any access to session data that has been set previously against that session id.
If the attacker knows what hashing you are using then they can crack it. And if you want to add a salt you have to send it to the browser and the attacker could intercept it. Using the time as a salt also won't work because there is only a relatively short amount of time so they can solve that as well.
I'd like to securely save a user's credentials to related web sites and automatically log them into those sites when they log onto ours. I understand there are some security implications to this, so I'd like others' feedback and see what has been successful for others in the past.
What technique have you used to auto-log the users in? I'd prefer not to have to duplicate the HTML form and submit it through javascript. This seems error-prone if the form ever changes. I tried putting the login form inside an iframe, but it seems like the owners of the site are able to block this (see attached screenshot). Do you know how they do this?
Secondly, what was your approach to save the credentials so that they were "safe".
...Peter
I would suggest using cookies to save a session certificate to the users machine. A good value for such a cookie would be;
userid, timestamp, hash(userid . timestamp . global_secret)
The value of global_secret needs to be very long (40 characters or so), to avoid people cracking the hash, as doing so would allow them to create their own credentials with other peoples user ids!
The 'other sites' would check for this cookie, calculate the hash using the cleartext values of userid, timestamp and the global_secret (which all sites know), check it against the hash supplied, if they match, then this is a valid certificate.
You would then need to check the timestamp and decide if this was a 'new' enough certificate to allow access.
This is the standard method.
Do not do this. Read the terms of services for each site (ie facebook):
https://www.facebook.com/terms.php?ref=pf
(3.2) You will not collect users' content or information, or otherwise access Facebook, using automated means (such as harvesting bots, robots, spiders, or scrapers) without our permission.
(3.5) You will not solicit login information or access an account belonging to someone else.
(4.8) You will not share your password, (or in the case of developers, your secret key), let anyone else access your account, or do anything else that might jeopardize the security of your account.
You put yourself and the user at risk.
These sites have an API for a reason, so I suggest you looking using those as a more "legal" approach.
So if you're trying to retrieve a facebook user's information, create an app, have them authorize your app, then retrieve the information through facebook's api (example). You can also post to their wall with this method.
https://developers.facebook.com/
https://dev.twitter.com/
https://developers.google.com/
The common method to auto login a user is to set an cookie with an random string. It have to be that the random string isn't guessable. At the server you check the cookie and if it matches then you login the user. But if your site isn't completely served with https everyone who can listen to the traffic can pretend to be the user. To increase the security a little bit you could implement that a random string is only valid for a view days and then the user has to login again and a new random string is generated. So if someone steals the cookie-id the attacker has only for a certain time access to the account.
I am building a web app and have noticed that other web apps (gmail in particular) use cookies and it logs you out if you don't have cookies enabled. Any idea what these cookies are used for that they are so crucial? Are there any common uses for cookies in web apps?
It enables the server to maintain a client-specific state across requests (session) in the server side. It also enables JavaScript to maintain a client-specific state across requests in the client side without need for server interaction.
A cookie is a small piece of data (name-value pair) sent from a website (sever side) and stored in a user's web browser while the user is browsing that website. Cookies were designed to provide stateful information about user interaction in spite the stateless nature of HTTP protocol. Cookies can be categorised based on its nature.
Types of cookie can be selected based on the capabilities you want the cookie to have.
Session cookie
A session cookie, also known as an in-memory cookie or transient cookie, exists only in temporary memory, while the user navigates the website. (In java, Session cookie can be created by calling getSession() on request object). Web browsers normally delete session cookies when the user closes the browser. This type of cookies may be used to maintain data related to the user during navigation but in the same session. User can go back and forth on website without affecting the preferences but the moment browser is shut down or session timeout, all preferences will be lost.
Persistent cookie
A persistent cookie outlasts user sessions if you does not set the max-age. To retain the cookie beyond the user session, you have to set Max-Age for that cookie. Cookie must have data (name-value pair) which will sent back to the server every time the user visited the website. This could be used to record a vital piece of information such as how the user initially came to this website or the preferences made etc. Persistent cookies may be used to maintain data related to the user during navigation, possibly across multiple visits in different time. Persistent cookies store user related data which will be used for future visit to website. Persistent cookie can be used as shopping cart to which users can store items they want to purchase as they navigate throughout the site or in future.
Secure cookie
A secure cookie has the secure attribute enabled and is only used via HTTPS, ensuring that the cookie is always encrypted when transmitting from client to server. This makes the cookie less likely to be exposed to cookie theft via eavesdropping. In addition to that, all cookies are subject to browser's same-origin-policy.
As you asked about Gmail cookie mechanism, yes Gmail is using this secure cookie mechanism to store username and random token as your credentials to login. Yes, it is not storing your original password in secure cookie instead when you successfully enter the correct username and password and say yes to remember my password, it generates a random number (token) for your username as a login cookie issued in addition to the standard session management cookie and store username and random number as password in its database. That cookie cannot be used by other device as it is using same-origin-policy. The username and token are stored as a pair in a database table. When a user again visits the site, the login cookie will be sent to the server in the request object automatically from browser, then the username and token are verified in the database by the server. If the pair is present, the user is considered authenticated. The used token is removed from the database. A new token is generated and stored in database with the username, and issued to the user via a new login cookie in the response object. If the pair is not present, the login cookie is ignored. Users entered via this mechanism are not permitted to access certain protected information or functions such as changing a password, viewing Personally Identifiable Information (PII). To perform those operations, the user must first successfully submit a normal username/password login form which will pop automatically when you tried to do these prohibited operations. Since this approach allows the user to have multiple remembered logins from different browsers or computers.
HttpOnly cookie
The HttpOnly attribute is supported by most modern browsers. On a supported browser, an HttpOnly session cookie will be used only when transmitting HTTP (or HTTPS) requests, thus restricting access from other non-HTTP APIs such as JavaScript. This restriction mitigates but does not eliminate the threat of session cookie theft via cross-site scripting (XSS). This feature applies only to session-management cookies and not on other browser cookies.
Third-party cookie
Third-party cookies are cookies that belong to domains different from the one shown in the address bar. It is mostly used for advertisement by keeping tracks of user preferences and browser history to judge its inclination and sell him something accordingly.
Cookies maintain data that pertains to the user, and it resides on the user's computer (i.e. browser cookies), so that it gets loaded when they come back to the site, even after a few days, or even much longer than days.
Here are some examples of information that makes sense the most to be in a cookie:
The user's choice of ordering in a column
The user's color theme of a web page
The user's preference of article categories (such as Google News sections)
You might say "why not save it in a database and have the server handle it?"
Well, cookies also allow you to maintain a user's preferences without requiring them to create an account that will track their settings.
You might also say "why not keep it in the Session of the web app (such as in ASP.NET)?"
The Session is wiped when the user leaves the site, so the settings won't last until they come back again.
As others have said Cookies are used for maintaining state. The meta-reason why they're used is because HTTP is a stateless protocol but business reality demands state persistance somehow.
One thing not mentioned so far is that cookies are also used to store authentication information (as well as application state). This would explain why you're automatically logged out on gmail when you turn cookies off. If google can no longer determine which user you are, then they can't give you access to your email.
Cookie is data set by server and presented by UA to the server on each request. The purpose is to preserve state between requests (remember, HTTP is stateless protocol). This give a broad range of uses, from keeping simple preferences to identifying particular UA amongst the others (that how GMail identifies you and your account when you logged in)