What does `<script>` do, in a url? - session

In this document, page 7, it describes a vulnerability that may happen when a user is tricked into going to
"http://online.worldbank.dom/<script>document.cookie="sessionid=1234;domain=.worldbank.dom”;</script>.idc". (They also include a url with <meta> at the end, as an example.) I noticed that at least in Firefox, this only gives 404 error. For example, http://example.iana.org/%3Cscript%3Ealert%28%27hi%27%29;%3C/script%3E.htm
I know there's javascript: "url" prefix, but was there also a bug in old browsers that somehow allowed scripts in the url? Or is this document implying something completely different?
One other thing I don't quite understand - on page 11:
"Notes: It’s important to realize that using an encrypted
communication between the user’s browser and the target web server has
literally no effect on the exploitability of session fixation
vulnerabilities."
It says this in the section that describes network sniffing and injecting, is that really possible with https??

The idea with session fixation is that the attacker doesn't need to pay attention to whether or not it's https. Sniffing is not needed.
Normally the attacker could try to steal a valid session id by sniffing, and then take over the user's session. With session fixation the attacker picks a session id, and then tricks the victims browser into using that preselected session id. Thus there is no need to sniff. The session id is already known.
Regarding script-tags in the url, that attack will work in some, but not all websites. If the website has (as described) a cross site scripting (XSS) then the attacker can craft a url with a fixation attack. However a more likely scenario is injecting scripts that steal the current session id, but this may not work if the session cookie is httpOnly. In this case session fixation might be a better option for the attacker.

Related

Is there a way to check the authenticity of the user, after changing the Session Cookie?

Steps to re-create the issue:
Login with Admin Credentials and copy the session cookie.
Open another browser, Login as another user, paste the session cookie of the admin. Refresh the page. Now, you'll be
logged in as Admin.
How to solve this issue? Any suggestions would be of great help.
Tried using the event subscriber to get the previous session before drupal loads the cookie session, but no luck with it.
This is not a problem, I mean, of course, Session Hijacking is a really big concern - but standard defences are fine.
These are the controls that I know are widely known/used:
Ensure HTTPS is used everywhere,
Only use a securely created random string for the cookie value,
Set the secure flag on all cookies. This will ensure that they are only sent over an SSL connection,
Change the session cookie on each new login attempt.
All of Drupal 8's cookies are secure by default.
The exception is BigPipe's no-JS cookie, see https://www.drupal.org/node/2678628 — but there are no security consequences there.
I know some very sensitive applications may also store - for each session - the following additional information:
SSL Session ID
HTTP User Agent
Remote IP Address
In my point of view, I wouldn't bother with checking the HTTP User Agent or the remote IP address. They don't add that much security and they will break legitimate use in certain scenarios. Checking the SSL session ID (SSL session binding) would be OK from a security perspective, but could be painful to implement, the other defences are fine.
If your concern is Cookie Theft via XSS, the best defence is to use standard methods to avoid XSS bugs in your web application. See OWASP for plenty excellent resources.
You may find a lot of best practices to write secure code for Drupal 8 here: https://www.drupal.org/docs/8/security/writing-secure-code-for-drupal-8
You may also find a pretty old discussion about this on Drupal here: https://www.drupal.org/project/drupal/issues/19845

AJAX withCredentials not passing along cookies in Safari

I have a single-page static app hosted at example.com. My server for the app is hosted at server.com. I keep these two services completely separate and they can scale differently this way. When the user wants to login their username and password is passed to yoyoma.com and a cookie is set on server.com with the access_token. The user is then redirected to example.com and is now logged in.
From the static app at example.com, we can now make AJAX requests to server.com setting withCredentials=true so that the access_token we set is passed along to server.com. This works perfectly in every browser but Safari. The only way I've gotten Safari to work is by going to preferences -> privacy -> disabling "Prevent cross-site tracking". I know that the cookies are getting set on server.com, but they don't get passed with the AJAX request. It seems to be some Privacy feature that Apple thinks is just wonderful, but how are you supposed to get around this issue. I'm not an ad service, I'm not doing anything evil, just trying to get my app to work. I specifically want to build a single page app where the server is on a different domain. Is this possible in Safari or has their privacy setting made this impossible?
Note: I should also mention to security fanatics that when the access_token cookie is set, the user is then redirected to example.com with a CSRF token. This csrf token is passed in every AJAX request by a header to prevent Cross Site Request Forgery.
Assuming you're set on keeping different domains - which is not at all unreasonable there are some ways to tackle it, but they come with compromises
1
Have example.com redirect to a server rendered server.com/login for creating the httpOnly cookie and then redirect them back to their logged in state in your SPA.
As I understand it, when Prevent cross-site tracking is enabled in Safari, the intention is to have the user interact with the other domain before cookies are allowed to be sent.
By redirecting them, that intent has been created and you should have no issue setting a cookie and have it be sent by example.com.
However it does come it its own set of limitations
Read more
2
Look into the discussion related to StorageAccess as the idea here is to work with third party auth solutions that rely on cookies from different domains. Safari ITP has sorta made those harder to use, so the idea is to work with vendors for a better solution than LocalStorage.
3
Store your key in LocalStorage, and vet all running javascript code coming from you and make sure to follow best practices when it comes to dealing with user created values.
LocalStorage exposes your to potential XSS, but Cookies expose you to CSRF attacks. You have to mitigate those and it's not too hard, but keep in mind you introduced those vectors when cookies were used.
Any XSS that happens is game over, even with httpOnly cookies. Forget your auth key, running the attackers code can do so much more damage.
Keylogger to take username/password
If the attack happens after an authed state, they could pop up a modal asking re-auth.
Submit a request to change email and then ask for password reset
Don't get me wrong, it's easier to dump LocalStorage as a generic attack versus the attacks listed above
That being said, in the end the resources you spend on dealing with cookie issues, could be better spent hardening down your javascript running on the users browsers to ensure they aren't running malicious code
You can't protect them from extensions though, and a httpOnly cookie would at the very least ensure that their keys aren't leaked. Know your compromises.
Edit: Keep in mind that whatever approach you're taking, any further reliance on browser needs to think through the different versions of browsers out in the wild. As an example, don't assume using httpOnly cookies and setting a sameSite policy negates the need for a CSRF token. Any addition of cookies might s till need a CSRF token as a header as of today unless it's a controlled environment.
Personal Opinion held loosely.
Do no harm. Cookies add "harm"/work that you have to mitigate.
Cookies might protect attacks leaking access tokens but why would an attacker care about the access token when they can run any code they wish?
LocalStorage weakness is XSS, but Cookies does not protect against that.
What prevents them from just taking the password?
Popping up a login modal to an unexpected user that won't think twice, hell Github does that from time to time for good reasons, it's not unheard of.

How to protect my JSESSIONID from document.execCommand(“ClearAuthenticationCache”)?

This might be a duplicate of this question, but the solution proposed isn't viable for us:
Protect against 3rd party callers of document.execCommand("ClearAuthenticationCache")? Clears our session cookies
Long story short: IE has a way to clear session cookies using JavaScript - document.execCommand(“ClearAuthenticationCache”). This is used in a variety of web apps including Outlook Web App (and presumably many others). Problem is MS in their infinite wisdom decided that this command should clear session cookies for all open sites (can you tell I'm a little bitter, it took me months to find the source of randomly missing JSESSIONIDs).
We use JSESSIONID as well as another token to make sure the user is authenticated. The JSESSIONID is secure and httpOnly. This works well except when the JSESSIONID is wiped out by a third party. So my question is in two parts:
Is there a way I can protect my session cookies from this (let's assume anything involving client side configuration, such as pinning or registry hacks, is a non-option)?
If not, is there a way for me to securely recover from this? Since the JSESSIONID is httpOnly, the browser shouldn't be able to read it, but maybe there is something I'm not thinking off.
If relevant: we use Tomcat 7 as our webserver. The app is a fairly complex SaaS app, and security is fairly important.
Thanks all.
I believe either of the following options would work to protect servlet sessions from document.execCommand(“ClearAuthenticationCache”):
You could set the max-age of your JSESSIONID in your web.xml. That way your JSESSIONID cookie would no longer be a session cookie! This would make your web application slightly less secure as the cookie would still survive after the browser is closed.
You could abandon HTTP cookies altogether and configure Tomcat to do session tracking with the SSL session ID. I've never actually configured it myself, but I would guess that this is more secure than using JSESSIONID cookies. However, session replication is not possible in this configuration.

Website sessions with disabled cookies, javascript, HTTP Referer and without GET/POST?

My problem is probably a very common one ;)
I want to implement user sessions for a website. The restrictions for this to work are these:
It has to work without cookies, since they can be disabled.
It has to work without passing the session id (or session-related id) inside the GET and/or POST form variables.
It has to work without inspecting the HTTP Referer header field, since this might be empty.
It has to work without JavaScript, since this can be disabled.
The only thing I found was using HTTPS (which is a good choice anyway...) and "Digest access authentication". The only shortcoming is that MD5 is used as the hashing mechanism which is considered insecure.
Is there any way of establishing a user session that cannot be hijacked easily by applying the restrictions mentioned above? And does Digest access authentication solve this and what might be the shortcomings?
Edit:
I found another approach that might work: If the site is HTTPS only then one can grab the SSL/TLS session identifier on the server side (e.g. using mod_perl if using Perl on server side) and use that session id. Note that user association with one such session id must be done separately. But still with this approach the server side always has a valid secured session id.
Is this correct?
As mentioned here: https://security.stackexchange.com/questions/48856/is-using-an-ssl-session-id-along-with-a-cookie-based-session-verification-more-s
The easiest and most secure approach (given the information I gathered until now) seems to be:
The Website is HTTPS only.
The session id is the SSL/TLS session identifier and this id is stored in a database and may or may not be associated with a user account record (user authentication is done using normal forms over HTTPS then).
If anyone has a better approach, I would be glad to read about it.

What's the best way to use HTTP Authentication in an Ajax Application that's not 100% AJAX

I have a standard HTML login page, which I would much rather use than the standard HTTP authentication pop-up provided by browsers. Today, I am using session cookies to keep track of the session after logging in, but I'd like to be stateless and pass the HTTP authentication every time. The web services I am hitting already support this, so this is a browser-only issue.
Adding authentication credentials is trivial in jQuery, but I don't know how to keep them around. If you go from the login page (a jsp) to the Home page (another jsp) you clearly don't keep the username and password fields from the login page. I know some browsers will store your HTTP authentication credentials if you enter them from the pop-up, but I don't know if they get stored when using an XHRRequest. If they do, is there much consistency among browsers?
Also, the user needs to be able to "sign out" of the application, too. If the browser stores the authentication credentials, is there a way to clear them using JavaScript.
I feel like I can't be the first person to try to solve this. Is there some jQuery plugin or something that already handles this? Or is it simply not possible to do what I'm trying to do?
You have 2 options:
1) Client-side storage of credentials -- not a good idea. For obvious reasons you don't want to store the username/password on the client. If you had a hashed version of the password, it might not be so bad, but still not recommended. In any case, if you're going to store on the client side, you either have to use a cookie, or HTML5 local storage (which is not widely supported, yet)
2) Server-side storage of credentials -- typically done with sessions. Then the resultant Session ID can be passed back to the client and persisted in either a cookie or in the URL of each subsequent AJAX call (?SESSID=xyz for example)
The server-side approach would be the most secure, reliable, and easiest to implement
Okay, I'll take a stab at helping ...
Firstly, understand how HTTP authentication works. There are two versions - Basic and Digest. Basic transmits in plaintext, digest is encrypted. With these types of authentication, the username/password are passed in the HTTP header with every single request. The browser captures these at login and they are stored in an inaccessible browser session cookie which is deleted when the browser session is closed. So, in answer to one of your questions, you can't access these from javascript.
You could create your own session cookie variables for username and password. The jQuery functions for this are really simple. See jquery-cookie module as one example of how to set session cookies. These could be retrieved from the session cookie and sent with each ajax request and validated in the server. However, this is not a particulary good way to do authentication since sniffing the network will allow anybody to easily grab your auth details. But, it would work.
Using session cookie based authentication where the session ID is sent sent with each request is the best way to do this. At the server side, you need to have a function called for every HTTP request. This function should do the following:
check to see if the session has been authenticated
if no:
redirect to login screen
if yes:
do authorization and allow the user access to the page
Most web frameworks support session cookie authentication and the management of session ids at the server. This is definately the way to go.
This is interesting one.
Manage user sessions on server by use of cookies. Create a session when user first accesses the login page and pass the session id/key as value to one of the cookie via response. When the user is authenticated put user "key" info in cookie and "values" in application context at server. Once user is logged, any subsequent request will be authenticated based on session cookie value at server. Authorization will be done based on user "key" passed as cookie value.
On logout clear the session based cookies from server and refresh the site to default page.
Cookies are bizarre with different browsers - just a note ;)
Hope this helps.
Update
The answer below was posted in 2012 and the links are mostly dead. However, since then, a more elegant standards-based approach to the same solution appeared using JSON Web Tokens. Here is a good blog post explaining how to use them.
Most answers miss the point, which is to avoid having any server-side session. I don't want any application state in the server. I'll award the bounty to answer that came closest, but the real credit goes to the rest-discuss group and Jon Moore for the correct answer and to Mike Amundsen for helping me to actually understand it.
The best answer I've gotten is to use a cookie, but not the typical automatic session id cookie given to you by most application servers. The cookie (which will automatically be sent with each subsequent request) is a user identifier and time signed by the server. You can include an expiration time with the cookie so it simulates the typical 30 minute session on a server (which means you have to push it forward with subsequent requests) as well as keeps the same cookie from being valid forever.
The XHR/AJAX part is a red herring. This will work whether you are doing XHR requests or an old-fashioned page-by-page web application. The main points are:
The cookie is automatically sent on subsequent requests so there's no
special scripting required - it's just how browsers work already.
The server does not need to store any session for the user, so the user
can hit any server in a cluster and not have to re-authenticate.
Slightly interesting in that you consider pushing some of the authent to the client. If you want a conventional solution, KOGI's server-side suggestion is the way to go.
But you also seem to be asking questions about memory leaks involving your user supplied secrets. Good questions. But to take a general stab at answering that I'd say it would have to be browser specific. It's browser internals, javascript engine internals -dependent where a client side application (i.e., the browser, or js in the browser) is storing the values the user inputs.
Most likely those values are not replicated needlessly throughout memory, but there's no way to guarantee that. Apart from responsible javascript coding practices, there's nothing you can do to guarantee the limit of locations of user inputs.
Slight digression
The basic point is if you store it on the client it is not really secure -- unless, the serve stores encrypted information on the client with a key that only the server (or the user via their correct credentials), has. So you could conceivably code a JS application to do some authent on the client -- much the same as how bank card (used to?) do POS authent by checking the PIN to the PIN on the card, and not back at the DB. It's based on the (somewhat flimsy) assumption the user has no direct read/write access of the "dark area" cookie/local storage on client / mag strip on bank card. So I would only advise this as disqualifier for false authents and not as a sole qualifier for the credentials.
Main point
If you do want to be stateless, just store user credentials in localstorage, or as a cookie but encrypt them with a server key. When you need them send an XHR with the encrypted / use stored credentials to the server over HTTPS, let your server decrypt them and send them to the callback. Then pass those cleartext of HTTPS to do your authent.

Resources