URL Rewriting vulnerability - security

We modified our Session handling from cookie based to URL Rewriting. By doing this the session id gets transmitted as part of the URL.
Now there is a vulnerability issue, where whoever uses this URL will be able to log in into the system.
To resolve this issue we have done the following
[1] A HTTP Session Listener has been created to maintain list of HTTP sessions.
Listener reacts on the events when session are created or destroyed.
[2] A Session Filter has been created to verify HTTP Session and check its integrity against HTTP Request attributes
Session will be invalidated in case Request attributes (identifying the client origin) do not match original attributes stored with session. (to block the session hijack attempt)
However i think that this has a gap, when you are trying to access over a proxy etc.
Is there any other effective solution for this?
Also we cannot use third party libraries to resolve this because of the nature of the produce.

So you need to be doubly careful with session ID likes this: users share URLs! The definitive advice on the subject comes from OWASP:
https://www.owasp.org/index.php/Session_Management_Cheat_Sheet
But I think you should consider the following additional controls:
Rotating the session key on each request. This is only practical with simple web applications though. It'll cause problems undoubtedly with AJAX and might be difficult to manage if the user is likely to open a second tab on the application.
Shorter timeouts.
I am presuming that in the 'HTTP Request Attributes' you mention you are already picking up the User-agent, source IP address and invalidating the session if these are inconsistent.
If you are using SSL it might be possible to do a great solution where the session ID is tied to the SSL connection (Apache, for example, exposes this in a SSL_SESSION_ID environment variable). But this information might not be available to your application.

Related

Harm of passing session id as url parameter

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?

Are security concerns sending a password using a GET request over https valid?

We have webpage which uses the sapui5-framework to build a spa. The communication between the browser and the server uses https. The interaction to log into the page is the following:
The user opens the website by entering https://myserver.com in the browser
A login dialogue with two form fields for unsername and password is shown.
After entering username and password and pressing the login-button
an ajax-request is send using GET to the URL: https://myusername:myPassword#myserver.com/foo/bar/metadata
According to my understanding using GET to send sensitive data is never a good idea. But this answer to HTTPS is the url string secure says the following
HTTPS Establishes an underlying SSL conenction before any HTTP data is
transferred. This ensures that all URL data (with the exception of
hostname, which is used to establish the connection) is carried solely
within this encrypted connection and is protected from
man-in-the-middle attacks in the same way that any HTTPS data is.
An in another answer in the same thread:
These fields [for example form field, query strings] are stripped off
of the URL when creating the routing information in the https packaging
process by the browser and are included in the encrypted data block.
The page data (form, text, and query string) are passed in the
encrypted block after the encryption methods are determined and the
handshake completes.
But it seems that there still might be security concerns using get:
the URL is stored in the logs on the server and in the same thread
leakage through browser history
Is this the case for URLs like?
https://myusername:myPassword#myserver.com/foo/bar/metadata
// or
https://myserver.com/?user=myUsername&pass=MyPasswort
Additional questions on this topic:
Is passsing get variables over ssl secure
Is sending a password in json over https considered secure
How to send securely passwords via GET/POST?
On security.stackexchange are additional informations:
can urls be sniffed when using ssl
ssl with get and post
But in my opinion a few aspects are still not answered
Question
In my opinion the mentioned points are valid objections to not use get. Is the case; is using get for sending passwords a bad idea?
Are these the attack options, are there more?
browser history
server logs (assuming that the url is stored in the logs unencrypted or encrypted)
referer information (if this is really the case)
Which attack options do exist when sending sensitive data (password) over https using get?
Thanks
Sending any kind of sensitive data over GET is dangerous, even if it is HTTPS. These data might end up in log files at the server and will be included in the Referer header in links to or includes from other sides. They will also be saved in the history of the browser so an attacker might try to guess and verify the original contents of the link with an attack against the history.
Apart from that you better ask that kind of questions at security.stackexchange.com.
These two approaches are fundamentally different:
https://myusername:myPassword#myserver.com/foo/bar/metadata
https://myserver.com/?user=myUsername&pass=MyPasswort
myusername:myPassword# is the "User Information" (this form is actually deprecated in the latest URI RFC), whereas ?user=myUsername&pass=MyPasswort is part of the query.
If you look at this example from RFC 3986:
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
| _____________________|__
/ \ / \
urn:example:animal:ferret:nose
myusername:myPassword# is part of the authority. In practice, use HTTP (Basic) authentication headers will generally be used to convey this information. On the server side, headers are generally not logged (and if they are, whether the client entered them into their location bar or via an input dialog would make no difference). In general (although it's implementation dependent), browsers don't store it in the location bar, or at least they remove the password. It appears that Firefox keeps the userinfo in the browser history, while Chrome doesn't (and IE doesn't really support them without workaround)
In contrast, ?user=myUsername&pass=MyPasswort is the query, a much more integral part of the URI, and it is send as the HTTP Request-URI. This will be in the browser's history and the server's logs. This will also be passed in the referrer.
To put it simply, myusername:myPassword# is clearly designed to convey information that is potentially sensitive, and browsers are generally designed to handle this appropriately, whereas browsers can't guess which part of which queries are sensitive and which are not: expect information leakage there.
The referrer information will also generally not leak to third parties, since the Referer header coming from an HTTPS page is normally only sent with other request on HTTPS to the same host. (Of course, if you have used https://myserver.com/?user=myUsername&pass=MyPasswort, this will be in the logs of that same host, but you're not making it much worth since it stays on the same server logs.)
This is specified in the HTTP specification (Section 15.1.3):
Clients SHOULD NOT include a Referer header field in a (non-secure) HTTP request if the referring page was transferred with a secure protocol.
Although it is just a "SHOULD NOT", Internet Explorer, Chrome and Firefox seem to implement it this way. Whether this applies to HTTPS requests from one host to another depends on the browser and its version.
It is now possible to override this behaviour, as described in this question and this draft specification, using a <meta> header, but you wouldn't do that on a sensitive page that uses ?user=myUsername&pass=MyPasswort anyway.
Note that the rest of HTTP specification (Section 15.1.3) is also relevant:
Authors of services which use the HTTP protocol SHOULD NOT use GET based forms for the submission of sensitive data, because this will cause this data to be encoded in the Request-URI. Many existing servers, proxies, and user agents will log the request URI in some place where it might be visible to third parties. Servers can use POST-based form submission instead
Using ?user=myUsername&pass=MyPasswort is exactly like using a GET based form and, while the Referer issue can be contained, the problems regarding logs and history remain.
Let assume that user clicked a button and following request generated by client browser.
https://www.site.com/?username=alice&password=b0b123!
HTTPS
First thing first. HTTPS is not related with this topic. Because using POST or GET does not matter from attacker perspective. Attackers can easily grab sensitive data from query string or directly POST request body when traffic is HTTP. Therefor it does not make any difference.
Server Logs
We know that Apache, Nginx or other services logging every single HTTP request into log file. Which means query string ( ?username=alice&password=b0b123! ) gonna be written into log files. This can be dangerous because of your system administrator can access this data too and grab all user credentials. Also another case could be happen when your application server compromise. I believe you are storing password as hashed. If you use powerful hashing algorithm like SHA256, your client's password will be more secure against hackers. But hackers can access log files directly get passwords as a plain-text with very basic shell scripts.
Referer Information
We assumed that client opened above link. When client browser get html content and try to parse it, it will see image tag. This images can be hosted at out of your domain ( postimage or similar services, or directly a domain that under the hacker's control ) . Browser make a HTTP request in order to get image. But current url is https://www.site.com/?username=alice&password=b0b123! which is going to be referer information!
That means alice and her password will be passed to another domain and can be accessible directly from web logs. This is really important security issue.
This topic reminds me to Session Fixation Vulnerabilities. Please read following OWASP article for almost same security flaw with sessions. ( https://www.owasp.org/index.php/Session_fixation ) It's worth to read it.
The community has provided a broad view on the considerations, the above stands with respect to the question. However, GET requests may, in general, need authentication. As observed above, sending user name/password as part of the URL is never correct, however, that is typically not the way authentication information is usually handled. When a request for a resource is sent to the server, the server generally responds with a 401 and Authentication header in the response, against which the client sends an Authorization header with the authentication information (in the Basic scheme). Now, this second request from client can be a POST or a GET request, nothing prevents that. So, generally, it is not the request type but the mode of communicating the information is in question.
Refer http://en.wikipedia.org/wiki/Basic_access_authentication
Consider this:
https://www.example.com/login
Javascript within login page:
$.getJSON("/login?user=joeblow&pass=securepassword123");
What would the referer be now?
If you're concerned about security, an extra layer could be:
var a = Base64.encode(user.':'.pass);
$.getJSON("/login?a="+a);
Although not encrypted, at least the data is obscured from plain sight.

GWT Sessions and XSRF - the optimal solution?

Ok, first I was a bit confused when reading
Remember - you must never rely on the sessionID sent to your server in
the cookie header ; look only at the sessionID that your GWT app sends
explicitly in the payload of messages to your server.
at https://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecurityFAQ because I didn't understand the nature of XSRF completely and thought: why does it matter how the id gets transmitted?
Then I read http://www.gwtproject.org/doc/latest/DevGuideSecurityRpcXsrf.html and now I understand that XSRF works despite NOT knowing the cookie content (your browser just attaches it to the request, so you exploit your browser's knowledge of the cookie's content - although the browser does not tell 'YOU' or the attacker about the content. The cookie content itself remains uncompromised by that attack). So any proof of knowing the cookie's content validates that the request is not part of XSRF.
I don't like the solution as implemented by GWT (http://www.gwtproject.org/doc/latest/DevGuideSecurityRpcXsrf.html) because it needs a separate call to the server. Please tell me if my ansatz is secure and if I understand the XSRF stuff correctly:
To prevent XSRF, I just copy the session ID contained within the cookie into some non-standard HTTP header field, ie. "X-MY-GWT-SESSION-ID: $sessionId", when doing RPC calls.
That way, I do not need to make any additional calls during app startup because session validation is already done during delivery of the gwt app by destroying the cookie if the session is not valid any more (see How can delete information from cookies?).
So here is the complete security implementation:
registration: client submits cleartext credentials via RPC call to the server, which in turn stores the password using a hash during registration in the server's database (How can I hash a password in Java?)
login: client sends cleartext pwd via https+RPC, check password on server, if ok: store and return (via https) random UUID. That UUID is the shared secret stored on server and client that is used to identify the authenticated user over possibly many browser sessions to avoid requiring the user to log in each time he visits the site.
server sets cookie expiry time to 0 if session is not valid any more so that the client clears the session id and the GWT app detects that it needs to re-authenticate.
on server side only accept session UUIDs sent through a special HTTP header field to prevent XSRF
handle invalidated sessions on client side (either no session cookie or RPC request produced auth failure)
to prevent re-authentication shortly after gwt app loading, the server side devlivery mechanism (ie. index.jsp) deletes the cookie some time before the timeout actually happens - delivering a page and asking for authentication a few seconds later is a bit dumb.
Example sources for the GWT part can be found there: https://stackoverflow.com/a/6319911/1050755. The solution bsaically uses GWT XSRF classes, but embeds the MD5-hashed session ID directly into the web page instead of getting the token via a separate RPC call. The client actually never calls any cookie-related code and the server has only embedded a request.getSession().getId() call into the jsp page.
Any comments, suggestions, critique? Do I miss something important?
Disclaimer: I'm not a security expert.
Actually, if you obtain your xsrf token by an RPC call, then you're subject to XSRF, as an attacker could possibly forge both requests (this is very unlikely though, because it would have to read the response of the first call, which is most of the time prohibited by the cross-origin nature of the request and/or the way it has to be executed).
So ideally you'll make your xsrf token available to the GWT app through any mean.
You'll generally want your session cookie to be unaccessible through scripts (HttpOnly flag), so you'll need to find another way of passing the value (e.g. write it in the HTML host page that's delivered to the browser –as a JS variable, or a special HTML attribute on a special HTML element–, and read it there with GWT, either through Dictionary, JSNI or the DOM).
Also, you'll probably want to use both the cookie and the request header to validate the request (they must match), or you might be vulnerable to session fixation attacks (would probably need an XSS vulnerability too to make it truly useful)

Can I disable a cookie from being sent automatically with server requests?

I'm fairly new to website development. I'm working on a site where the user logs in with username/password, and gets a sessionID from the server in response. This sessionID is sent back to the server (and a new one returned) with each request.
I'd like the site to work properly if the user opens it in multiple tabs or windows. i.e. once logged in at one tab, opening a members-only URL in another tab works without loggin in. (And, logging out in one tab logs out from all.) I see no way of doing this without storing the latest sessionID in a cookie. That way the latest sessionID can be "shared" among all tabs.
However I am starting to read up on cookies, and some of the security threats. I was unaware that cookies were sent with every request. I don't need to send my cookie to the server, ever. The sessionID is added to the xhr request's headers -- not read as a cookie. So I'm wondering if there is a way to disable sending of this cookie. My only purpose for it is to allow multiple tabs/windows in the same browser to share the same session.
I was reading up on the path parameter for cookies. Apparently this can be used to restrict when the cookie is sent to a server? What if I set the path to something that would never be used? Would this prevent the cookie from ever being sent out automatically? I only want to access it from JavaScript.
A coworker has put a lot of safeguards into the server-side of this application, which I won't go into here. So this question is just about what client-side precautions I can and should take, particularly with cookies, for optimal security. If there is a better way to allow a members-only site to work properly with multiple tabs open at once, I'm all ears.
I discovered just now that in HTML 5 there is local storage, which stores key/value pairs much like a cookie, but is not sent with every server request. Since it's supported in every browser except IE 7 and earlier, I'll be switching to this to enable sharing data between tabs when available, and use cookies instead on IE 7 and earlier.
The sessionID is stored in a cookie already there's no need to manage it. Because the HTTP protocol is stateless the only way to maintain state is through a cookie. What happens when you set a session value the server will look up the dictionary of items associated with that cookie id (session Id).
What is meant by stateless is that between requests HTTP does not know if your still alive or have closed your browser. Therefore with each request the browser will attach all cookie values to the request on the domain. SessionId is stored in the cookie automatically when they go to your site. The Server then uses that value to look up anything you've set in the users session.
Depending on which programming language and/or server you're using the session could be handled differently but that's usually abstracted away from the programmer.
Now with respect to sessions, there are a number of different things that make them insecure. For example if an attacker were able to get their hands on your session cookie value they could replay that cookie and take over your session. So sessions aren't a terribly secure way of storing user information. Instead what most people do is create an encrypted cookie value with the users details, the cookie could be a "session cookie" meaning as soon as the user closes their browser window the cookie is thrown away from the browser. The encrypted cookie contains user information and role information as well as some identifier (usually the clients ip address) to verify that the user who is submitting the request is the same user the cookie was issued to. In most programming languages there are tools that help in abstracting that away as well (such as the ASP.NET membership provider model).
Check out some details on the HTTP protocol and HTTP cookies on Wikipedia first
http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
http://en.wikipedia.org/wiki/HTTP_cookie
and check out the membership provider model on ASP.NET, it's a really good tool for helping to secure your site.
http://msdn.microsoft.com/en-us/library/sx3h274z(v=vs.100).aspx
Preventing the browser sending cookies seems to defeat the object of using cookies in the first place.
If you don't want the sessionID to be sent with each request, why set the cookie? A better solution would be to use a custom response header that you send from the server to the browser - this will then be under your control and will not be sent automatically with all browser requests. You are using request headers to send your sessionID anyway so you could receive them from the server using a custom header and read this into your JavaScript from each XHR.

what is the vulnerability of having Jsessionid on first request only

Recently we removed jsessionid from URL did cookies based session management to prevent "session hijacking attack"
But we found that first request URL always has jsessionid when cookies are enabled and subsequent request URL has NO jsessionid.
using the jsessionid from first url we could directly hit other pages in the workflow
Question : is there any security vulnerability exposing jsessionid only on first request?
There is a solution to remove jsessionid from first request , but wanted to check , if its really vulnerable to mandate the changes
thanks
J
EDIT : I got my doubt clarified. Thanks for replies.
What you've done here could improve the overall security of the solution somewhat, but won't necessarily prevent session hijacking.
the security issue with placing the session ID in the URL is that URLs are exposed in various places (eg, copy and pasted URLs could expose a live session, URLs can be stored in proxy server logs, web server logs and browser history), which could allow an attacker to grab a valid session ID and get access to your users data.
Ideally you should remove the JSESSIONID from the URL in all places, and only use cookie storage.
Additionally if you want to mitiate Session hijacking there's a number of other areas to consider.
You need to use SSL on all pages where the session ID is passed (this is to mitigate the risk of the session ID being intercepted in transit (eg, the Firesheep attack).
If the session ID is set before you authenticate the user, you should ensure that a new session ID is issued when the user logs in.
Also if possible the session cookies should be use of the httpOnly and secure flags, to reduce the risk of them being leaked over cleartext channels.
There's some good additional information on the OWASP Site
BTW if you've got more question on the security side of things, there's a stack exchange site specifically for that at Security.stackexchange.com
did cookies based session management to prevent "session hijacking attack"
Whats stopping the cookie being hijacked?
Session managment is a server side thing - You need to server to check (based on the cookie) that the user is meant to be logged in.
I don't think you've improved security here at all to be honest, take a look at this excellent article to see why.
If someone gets hold of the session id then they pretty much hijack the whole session, see Predictable Session IDs vulnerability.

Resources