I read sessions and security questions on stackoverflow, and much beyond. I think I know the answer, but I want to confirm it with one concise simple question--security is too important.
Conjecture: My black hat web visitor does not have direct access to his $_SESSION contents.
that is, after my server executes
$_SESSION['myuserprivilege']='user' ;
I can assume that even the most clever blackhat cannot somehow find out even that my code did this, interrogate to what my php program set his server $_SESSION to (both keys and contents), or (much worse) engineer $_SESSION['myuserprivilege'] = 'admin'. only my own server php code can do so.
I still have to be concerned that a blackhat can steal the cookie of a different admin user ( => https and session rotation). but that's a different issue.
correct?
The values of the session are stored in your server, not in the user machine. So, no... No one can see or set that value without access to your server or any security problem in your code. It's like money in a safe, only who have access can get it or if the safe isn't secure enough.
And about cookie stealing, this is called session hijacking. It's common tecnique used to steal a session from another user. You can get more information here.
Basically if a person get the id of the session of a logged admin and the application doesn't have any approach to avoid this kind of situation, this person can have access to that user privileges.
Anyone can set a cookie in your website, but sessions has one thing called "PHP Session ID", so to get some value from a session, this person need to know a valid session id that have privileges to some part of application.
Session routation is not a problem, the chances to get some session from anyone that have this privileges is really, really hard. You also can use more characters in your session to make it more harder, but o don't think it's necessary.
Final answer: No one cannot set a session in our website, just who has access do the code and your server can do it.
Related
Hello fellow developers
I have obviously under estimated a thing when developing my first complex web site, where user creation and login is required.
It appears that cookies can be edited and modified by the user logged in, by using some developer tools i.e. in Google Chrome. That, I never gave a thought.
So, here is my issue.
When the user is logged in, I store the user name in a cookie.
If username-cookie is not blank, and I can find a user file with that name, the user is logged in, per se. Otherwise, no user is logged in.
When the user logs out, I simply expires the cookie, which works fine.
Now, the problem is, that a user obviously can edit the content of a cookie, outside the web application, or with javascript.
What would be the correct approach here to ensure, that the username cookie is not compromised in any way, other by my web application?
Making them read-only is not possible, I assume. Encrypting the cookie and then decrypting might work, I guess. Then, the cookie would be nonsense to the user, and if modified, result in a logout, as no valid username can be found upon decrypting the edited cookie.
I have stalked Googles cookies, and it appears that there are a lot of xxID cookies, which contains garbage. Does that mean, that encrypting/decrypting is the only way to make it work? I also considered some kind of login-ticket, but that would require a table lookup every time a user interacts with my web page.
Can anyone give me a hint as to what would be the correct approach?
Thanks in advance
Best regards,
Karsten Heitmann
You should look up session management for the language you are using.
The traditional approach is that when a user logs on, your application generates a long, cryptographically random token called the "session id" and sets that into a cookie. It stores data like who is logged in on the server side identified by the random value, so when a logged on user comes back, the browser sends the cookie with the random session id and the application can look up session data on the server side. This way an attacker has no way to guess a valid session id for a logged on user, assuming the session id is cryptographically random and long enough (which more precisely means it has enough entropy). Logging out means deleting the session data on the server side, and also removing the cookie, but that is not the most important part - the session will be invalid anyway.
Note that you should not code this yourself. You did not mention the language and environment you are developing in, but session management is rather tricky business if you want to secure it, and it is already provided by most languages / frameworks.
Just for curiosity, the encryption approach you mention is by the way a valid one. Some frameworks actually do that, but you should not attempt to code that either, because it is very easy to get it wrong, lots of things need to be taken care of to make it secure enough. Unfortunately an answer here is not the right format to go into details I'm afraid.
Btw you mention looking at Google. They use their own single sign-on solution, it is very complex compared to simple session management, so it's probably not the best example for you to look at. Find simple websites, most of those work the traditional way.
So I just noticed that one of the internet banks websites is passing session id as url parameter. ( See image below )
I didn't previously see anywhere that ';' in url, in this case it is after 'private;'.
1) What is the use of this ';'?
2) And why internet bank, which needs to be securest place in the internet is passing session id as url parameter?
At first, I thought they are doing it because some of the users disallow use of cookies, but then again, if they allow it, use cookies, if not - url, but I do allow use of cookies, so obviously thats not the case.
3) I guess then they should have some other security measures? What they could be?
4) And what one can possibly do if he knows others valid session id?
As I know, you can quite easily log into others peoples session if you know that id, because its not hard to edit cookies and its much easier to pass that session id as url parameter, especially if you have something like:
session_id($_GET[sessionid]);
Thanks!
1) You should ask whoever designed the application your red box is covering. URL can be anything you want; the convention of key=value&key2=value2 is just that - a convention. In this case, it's Java, and it commonly uses the convention of ;jsessionid=.... for its SID.
2) It's not that big of a deal. Normal users can't copy-paste cookies like they can copy-paste a GET parameter, but power users can do whatever they want (using Mechanize, wget, curl and other non-browser means, or even browser extensions). And if you allow it for some users and disallow for some, it's not really much of a security precaution, is it? Basically, cookie SID will make the attack a bit harder, but it's like putting your front door key under the mat - definitely doesn't keep your door secure. Additionally, cookies are shared between tabs: if a site wants you to be logged in with two accounts at once, you can't do it with cookies.
3) Serverside security, yes. One effective countermeasure is one-time SIDs (each time you visit a page, the server reads the session from the current SID, then starts a new session with a new SID for the next request). A less effective but still good method is to validate other information for consistency (e.g. - still same IP? Still same browser?)
4) Yes, if you know someone's valid SID, and the server does not adequately protect against session fixation, you can "become" that person. This might enable the attacker to, say, pay his bills with your money, for instance.
So, #Amadan correctly covered #1 and #4. But there's a bit more that needs expansion.
Using Session identifiers in a URL can be a major problem. There are a few cases where it's critically bad:
Session Hijacking:
If a user copy-pastes a URL into an email.
In this case, the attacker can simply read the email, and steal the session identifier (thereby resuming the session).
You could partially defend against this by making session lifetimes short, and validating things like IP addresses or User Agents in the session. Note that none of these are foolproof, they just make it "slightly" harder to attack.
If the connection is ever downgraded to HTTP.
If they are not using Http-Strict-Transport-Security (HSTS), then an attacker may be able to successfully downgrade the session to HTTP only (via MITM style attack). If the server isn't setup perfectly, this can cause the URL to leak to the attacker, and hence the session identifier.
Session Fixation Attacks
An attacker can craft a session identifier, and send the user a forged link with that session identifier. The user then logs in to the site, and the session is now tied to their account.
You can mitigate this by strictly rotating session identifiers every time the session changes (log in, log out, privilege upgrade or downgrade, etc). But many servers don't do this, and hence are susceptible to fixation style attacks.
The reason that cookie sessions are seen as more secure is not because they are harder to edit. It's because they are more resistant to fixation attacks (you can't create a URL or link or form or js or anything that sends a fraudulent cookie on behalf of the user).
Why the bank uses a URL parameter? I have two guesses:
Because they want to support those who don't allow cookies.
Which is sigh worthy.
They don't know any better.
Seriously. If it's not in a compliance doc or NIST recommendation, then they likely don't do it. Hell, there are implemented NIST recommendations that are known to be insecure, yet are still followed because it's in writing.
What is the use of this ;?
This is just a query string separator. & isn't the only sub-delim specified in the URL specification (RFC 3986).
And why internet bank, which needs to be securest place in the internet is passing session id as url parameter?
It could be that this session ID is never used, and the actual session identifier user is passed in cookies or in POST data between each navigated page. The only way to verify this is to try copying the URL into another browser to see if your session is resumed, however then again they may be checking things like User Agent - not real security but would dissuade casual attacks. Do not try this on a live system you do not have permission to do so on as it would be illegal. If you want to learn about security download something like Hacme Bank and try on there.
I guess then they should have some other security measures? What they could be?
No doubt they will, otherwise this would be a huge security threat. The URL could be leaked in the referer header if there are any external links on the page. The types of security a bank uses for their website is too large to list here, however they should be meeting certain industry standards such as ISO/IEC 27001 that will cover the types of threat that their site would need to be secure against.
And what one can possibly do if he knows others valid session id? As I know, you can quite easily log into others peoples session if you know that id, because its not hard to edit cookies and its much easier to pass that session id as url parameter, especially if you have something like:
As the ID is displayed on the screen it might be possible to read it (although IDs are generally long). A more realistic attack is Session Fixation. This is where an attacker can set the Session ID of their victim. For example, sending them a link that includes the attacker's Session ID. When the victim follows it and then logs in, as the attacker has the same session, they are logged in too.
Storing the Session information in a cookie or in a URL are both viable methods. A combination may used as
Security session management and (Server) Session management are separate aspects:
The fundamental difference is that cookies are shared between browser windows/tabs, the url not.
If you want your user to be logged on when navigating to the same site in different tab, sharing the security session (=without a new logon procedure) then cookies are a good way.
To differentiate "sessions" per tab and associate distinct server sessions with distinct tabs (Think of the user running two "stateful" transactions in two different tabs in parallel), managing a sessionId on the client which can be different per tab is required. Cookies won't work here.
Putting it in the URL is one way to assure this information is routinely added to requests fired from the page (referrer header). Alternative methods would require specific code to add this information explicitly to each request which is more work.
See How to differ sessions in browser-tabs?
I'm writing a GWT application where users login and interact with their profile. I understand that each form entry needs to be validated on the server, however, I am unsure about potential security issues once the user has logged in.
Let me explain. My application (the relevant parts) works as follows:
1 - user enters email/pass
2 - this info is sent back to the server, a DB is queried, passwords are checked (which are salted and hashed)
3. if the passwords match the profile associated w/ the email, this is considered success
Now I am unsure whether or not it is safe to pass the profile ID back to the client, which would then be used to query the DB for information relevant to the user to be displayed on the profile page.
Is there a possibility for a potential user to manually provide this profile ID and load a profile that way? My concern is that somebody w/ bad intentions could, if they knew the format of the profile ID, load an arbitrary amount of information from my DB without providing credentials.
-Nick
What you are dealing with here is a session management issue. Ideally, you want a way to keep track of logged in users (using random values as the session key), know how long they have been idle, be able to extend sessions as the user is using the site, and expire sessions.
Simply passing the profile ID to the client, and relying on it to send it back for each request is not sufficient - you are correct with your concern.
You want to keep a list of sessions with expiration times in a database. Every time an action is executed that needs user permissions (which should be pretty much everything), check to see if the session is still valid, if it is, extend it by however long you want. If it is expired, kill the session completely and log the user out.
You can store your session keys in a cookie (you have to trust the client at some point), but make sure they are non-deterministic and have a very large keyspace so it cannot be brute forced to get a valid session.
Since you're logging a user in, you must be using a backend that supports sessions (PHP, .Net, JAVA, etc), as Stefan H. said. That means that you shouldn't keep any ids on your client side, since a simple id substitution might grant me full access to another user's account (depending on what functionality you expose on your client, of course).
Any server request to get sensitive info (or for any admin actions) for the logged in user should look something like getMyCreditCard(), setMyCreditCard(), etc (note that no unique ids are passed in).
Is there a possibility for a potential user to manually provide this profile ID and load a profile that way? My concern is that somebody w/ bad intentions could, if they knew the format of the profile ID, load an arbitrary amount of information from my DB without providing credentials.
Stefan H is correct that you can solve this via session management if your session keys are unguessable and unfixable.
Another way to solve it is to use crypto-primitives to prevent tampering with the ID.
For example, you can store a private key on your server and use it to sign the profile ID. On subsequent requests, your server can trust the profile ID if it passes the signature check.
Rule 1 - Avoid cooking up your own security solution and use existing tested approaches.
Rule 2 - If your server side is java then you should be thinking along the lines of jsessionid. Spring Security will give you a good starting point to manage session ids with additional security features. There will be similar existing frameworks across php too (i did not see server side language tags in the question).
Rule 3 - With GWT you come across javascript based security issues with Google Team documents and suggests XSRF and XSS security prevention steps. Reference - https://developers.google.com/web-toolkit/articles/security_for_gwt_applications
I've implemented an login on a site (didnt use asp.net default). When a user logged in I save his ip in the db. If he doesnt doing anything in X min his ip get deleted. Whenever a user trying to enter a page that is restricted I check if his ip is on the db. If so he can continue.
The problem is that if the logged on user is on a wifi network or any other shared network, all the other users will have the same ip, and thats not good. How can I overcome this problem? Is cookies the best answer?
How is the user logging in? Username/Password? I'm assuming the password is stored as a salted hash in the database, so why not pass a cookie back with the user's username and hashed password? Whenever they try and access a restricted area check that username/password hash against your database. Make sure to sanatize the cookie values before checking them against your database to prevent injection. Or, depending on the language this is in, you could use session tracking.
I'm assuming by the tags that you're using WebLogic Server for your solution, although your comment about ASP.net makes me wonder. (although no ASP tags set for the question?)
The short answer is that you're making life harder than it needs to be - if I understand your problem correctly - that you want an idle user's session to be timed out after a certain period of inactivity for security reasons - then you can do this via application configuration with the session-timeout parameter:
http://download.oracle.com/docs/cd/E13222_01/wls/docs81/webapp/web_xml.html#1017275
Wherever possible when security's involved, I always prefer to avoid rolling my own solution. Just not smart enough to trust it. :-)
Apologies if I'm off in my understanding here.
I would like to improve security on a current application regarding session management and I want the users to be logged in until they explicitly logout.
How does one implement that securely?
Keep session information in database, like sessionid, ip, useragent?
Please provide the requirements, possibly a database layout, do's and don'ts, tips and tricks.
Note:
I know frameworks like asp.NET, rails, codeigniter, etc... already take care of that, but this is not an option. Actually it for a classic asp application. But I think this question does not relate to a specific language.
Read Improved Persistent Login Cookie Best Practice (both the article and comments).
You should know that such a system cannot be secure unless you use https.
It's quite simple:
User logs in.
The server sends the user a cookie with an expire date far in the future.
If you want, you can record the IP of the user.
User requests another page.
The server checks the cookie (possibly the IP stored with the cookie), sees that the user is logged in, and servers the page.
Some security considerations:
As stated above, there is no secure way unless you use https.
If you're using shared hosting, try to find out where your cookies are stored. Often they reside in the /tmp directory, where every user as access to and through that someone could possibly steal your cookies.
Track the IP, if you know that the computer isn't ever going to change it.
Don't store any information in the cookie. Just store a random number there and store the information belonging to it on the server in a database. (Not sensitive information like preferred colour can be stored in the cookie, of course.)
Create a cookie with a ridiculous expiry like 2030 or something. If you need session state, keep a session ID in the cookie (encrypted if security is priority) and map that to a table in a database. IP/UserAgent etc. tend to be meta-data, the cookie is the key to the session.