JSONP, Java Servlets, and Internet Explorer - java

I am using JSONP to answer AJAX calls on a different server than the site is on. It works pretty well, except that on IE, I can't maintain a session.
The site answering the request uses Java Servlets. It works in Firefox, but I in IE I have problems because it doesn't accept the cookies. (I can make it work by changing the security settings.)
From there I tried putting the sessionid in the url of the request:
listAction: server+'/site/gateway.jsp?current=page&next=something&jsessionid='+session+'&callback=?'
(I write callback=? because I am using jQuery and that is how you can do Jsonp.)
It still doesn't work. Did I write the session wrong? Is it still looking at my cookies? Can I possibly configure my servlet to load the session that I want it to load?

This is actually the same problem that you get with iFrames. You need to set a p3p header.
request.setheader('P3P: CP="NOI ADM DEV COM NAV OUR STP"');
Why does IE block you from using cookies with JSONP, but allow you if you just add some header? Who knows. The header represents a privacy policy. And I guess they don't think malicious hackers will be dishonest about their privacy policy.
If you sell information about your users or have other reasons to worry about a lawsuit from your users, you should make sure your p3p header accurately reflects your privacy policy, so you'll have to do a bit more research.
This is the same question but about the iFrames: Cookie blocked/not saved in IFRAME in Internet Explorer

Related

How can a servlet pass back to the browser the entire content of a proxied login result?

I promised to do something, but my managers want assurance that it can be done. What seems like a simple task is surprisingly hard to find example of. It consists of:
The browser asks a Java servlet for access to a remote site.
The servlet opens a HttpUrlConnection to that remote site.
The servlet sends a login request to that remote site.
The servlet receives a login form.
The servlet populates the login form from user session data, then
POSTs it.
The servlet receives the "welcome" from the remote site, complete
with headers and cookies.
The request of step 1 is finally filled by the content, headers, and cookies from step 6.
I'm having trouble getting code examples, leading me to think that what I want to do can't be accomplished. Can someone point me to an example?
Thanks,
Jerome.
The main problem is the domain of the session cookie.
More accurately, the question is what you're planning next after step 7.
Say your servlet is at "https://mycompany.com/loginServlet", and the remote site is a toy store "https://toys.com". Were you hoping that after step 7, the browser could be redirected to "https://toys.com" and get a proper service befitting a logged-in user? This won't work because when the browser received a session cookie from "mycompany.com" (in step7), this cookie will be attached to further requests for "mycompany.com" - but not to "toys.com", it's a security feature for excellent reason.
In short, this approach might work if both the servlet and the toys site are on the same domain. Though it makes me a bit uncomfortable in terms of security and password management, but never mind.
Obviously this approach would also work in the (unrealistic) case of letting your server proxy all further requests from the browser to "toys.com", but that's unrealistic for a typical commercial site (due to relative/absolute links, ajaxes etc.).
If it's different domains, then I second the wise comment made by "Rahul B" above: please look into SSO, and/or check with "toys.com" what login mechanisms they offer - maybe they already have something like "login with google" that's convenient enough.

Is it a good practice to check referer in the server-side form submission handler?

I am doing a Java web site. I hope to make the web site safer.
In my web site, all the forms are supposed (by design) to be opened in a page through a GET link from my website. I hope to check whether the referer is my web site in my server-side form submission handler. The idea is to avoid taking data from attacker-locally-generated form submission.
I feel that the key to this approach is whether the referer the server detects is reliable.
I understand that there are other ways to improve security. Let's just focus on the approach in my post.
Thanks for any input!
UPDATE
Specifically, I am doing a Spring MVC web site. I am using an interceptor to examine all traffic, especially the form submission.
No, it is not reliable. Some browsers may allow removing the referrer, or might not send it at all. And a naughty person can easily just add the referrer to the requests, so by itself it will not give any extra security except from random people trying random things.
Not the best way, but referer checking can help prevent Cross Site Request Forgery attacks:
Although it is trivial to spoof the referer header on your own
browser, it is impossible to do so in a CSRF attack. Checking the
referer is a commonly used method of preventing CSRF on embedded
network devices because it does not require a per-user state.
[snip]
...checking the referer is considered to be a weaker from of CSRF
protection. For example, open redirect vulnerabilities can be used to
exploit GET-based requests that are protected with a referer check and
some organizations or browser tools remove referrer headers as a form
of data protection.
Remember here that the attacker is not the one sitting at the keyboard - it is harder for them to spoof the referer from the victim's machine.
The strongest way of preventing CSRF though is the Synchronizer Token Pattern.

Do Applets use Browser for HTTP Requests?

Is there any interaction between applets and their hosting browser when making HTTP requests, or are requests made completely independently of native browser code?
Specifically, do Java applets running in a browser have some implicit way of sharing the browser's session state and cache?
I've read a few posts from non-authoritative sources saying that when an applet makes an HTTP request that it will use the browser's cache, and that it will also have access (somehow) to the browser's cookies.
Tests I've done using URLConnection suggest that this is not the case, and my gut feeling is that it sounds far too convenient to be true. I would assume that nothing in the JVM knows anything about the world outside of that JVM, meaning the only other way this could work would be if the JVM implementation is specific to the browser its implementation of the URL-related methods delegate to native browser code?
If cookie data is not implicitly shared or available, is best practice to pass a session ID in a param tag to the applet? Are there security concerns with this approach? If the applet doesn't use the browser's cache for requests, how does caching requests in an applet work?
Applets are executed by the Java Plugin, which is a browser plugin. The applet is indeed part of an HTML page loaded by the browser, can communicate with the browser DOM and with JavaScript code in the page, and uses the browser to send requests to its originating server.
See http://docs.oracle.com/javase/tutorial/deployment/applet/appletExecutionEnv.html and http://docs.oracle.com/javase/tutorial/deployment/applet/server.html for more information.
My testing with Windows 7, Java 1.6.23 and Firefox, Chrome and Internet Explorer is that HttpURLConnections from within an applet's JVM interact in no way with the browser. They don't use the cache, and don't have cookie headers added.
I think it depends on the Java plugin. My experience is that usually it uses the browser cache for network connections, and usually it transmits the cookies. I have had to empty the browser cache before to get a new file in an applet.
If you look at the Oracle Java 7 Plugin Control Panel, you will see an option in the network parameters to use direct connections for the applets, but the default is to use "browser parameters".
As for the cookies, I have seen in the past some Java plugins that did not transmit the session cookies, in particular on MacOS X (Apple even suggested a workaround). But most developers now assume that they are transmitted, and in practice it usually works.
Applets do not share the session information by default, but you can pass the session ID via Applet parameter while initializing. And use the session ID for each HTTP request.
Applets can interact with the browser to make HTTP requests via JavaScript calls.
If you use any Java HTTP APIs e.g. UrlConnection, Apache HTTPClient, java.net.Socket these libraries will not interact with the browser. They behave as if they were in a standalone JVM.
Caching id depenednt onthe API you use, Apache HttpClient has a cache. URLConnection lets you write your own cache easy enough.
You can not directly access the existing cache in JavaScript yet, its comming tho. https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage.
A param tag can not change once the page is rendered, e.g. OAuth tokens need refreshing periodically.
You could fetch cookies from the browser via JavaScript and manually add them to a Java initiated HTTP request. This mechanism allows them to be updated.
There is not much added risk sharing a cookie. You would have to remove the HTTPOnly flag on the cookie if there is one.
If you are allowing Java in the browser your users are letting you do pretty much anything. Java inside the browser does have a sandbox but its worryingly easy to break out. If you can design apps without Java they will be much more secure for users.
From the point of view of the person writing the Applet, Java is secure and much more flexible than JavaScript in a Browser.

Security matter: are parameters in url secure?

I have developed myself in the last few months about web development in java (servlets and jsp). I am developing a web server, which is mainly serving for an application. Actually it is running on google app engine. My concern is, although I am using SSL connections, sending parameters in the URL (e.g. https://www.xyz.com/server?password=1234&username=uname) may not be secure. Should I use another way or is it really secure? I don't know if this url is delivered as plaint text as whole (with the parameters)?
Any help would be appreciated!
Everything is encrypted, including the URL and its parameters. You might still avoid them because they might be stored in server-side logs and in the browser history, though.
Your problem seems to go further than Web Server and Google App Engine.
Sending a password through a web form to your server is a very common security issue. See this SO threads:
Is either GET or POST more secure than the other? (meaningly, POST will simply not display the parameter in the URL so this is not enough)
Are https URLs encrypted? (describes something similar to what you intend to do)
The complete HTTP request including the request line is encrypted inside SSL.
Example http request for the above URL which will all be contained within the SSL tunnel:
GET /server?password=1234&username=uname HTTP/1.1
Host: www.xyz.com
...
It is possible though that your application will log the requested URL, as this contains the users password this may not be OK.
Well, apart from the issues to do with logging and visibility of URLs (i.e., what happens before and after the secure communication) both GET and POST are equally secure; there is very little information that is exchanged before the encrypted channel is established, not even the first line of the HTTP protocol. But that doesn't mean you should use GET for this.
The issue is that logging in is changing the state of the server and should not be repeated without the user getting properly notified that this is happening (to prevent surprises with Javascript). The state that is being changed is of the user session information on the server, because what logging in does is associate a verified identity with that session. Because it is a (significant) change of state, the operation should not be done by GET; while you could do it by PUT technically, POST is better because of the non-idempotency assumptions associated with it (which in turn encourages browsers to pop up a warning dialog).

Client HTTP Post to external sites

Is there any web language that allows the client itself to create HTTP posts to external sites.
I know that JavaScript does this with XMLHttpRequest, but it does not allow cross-domain posting, unless the recipient domain wants to allow the sending domain.
I want to post data to an external site (that I don't control) and have the request be authenticated with what the client's browser already has (cookies, etc).
Is this possible? I tried cURL but it seems to make a server HTTP post, not a client HTTP post.
Edit:
A bit more insight of what I am trying to do:
I am trying to POST JSON to the website using the user's session (I said cookies but I believe they are PHP sessions, which I guess I still consider cookies).
The website does NOT check the referral (poor security #1)
I can execute javascript and html on the webpage using my personal homepage (poor security #2)
The JSON code will still work even if the content-type is form (poor security #3)
There is no security checking at all, just PHP session checking.
The form idea is wonderful and it works. The probably again is that its JSON. So having sent postdata as foo={"test":"123", "test2":"456"} the whole foo= part messes it up. Plus forms seem to turn JSON into form encoding, so its sending:
foo=%7B%22
test%22%3A+%22
123%22%2C+%22
test2%22%3A+%22
456%22%7D
when i need it to send;
{"test":"123", "test2":"456"}
So with everything known, is there a better chance of sending JSON or not?
I don't think so: You won't get hold of the user's auth cookies on the third party site from server side (because of the Single Origin Policy) and you can't make Ajax requests to the third party site.
The best you can do is probably create a <form> (maybe in an <iframe>), point it to the third party site, populate it with data, and have the user submit it (or auto-submit it). You will not be able to get hold of the request results programmatically (again because of the Single Origin Policy), but maybe it'll do - you can still show the request results to the user.
I think for obvious reasons this is not allowed. If this was allowed what would stop a malicious person from posting form data from a person's browser to any number of sites in some hidden iframe or popup window.
If this is a design of your application you need to rethink what you are trying to accomplish.
EDIT: As #Pekka was pointing out I know you can submit a form to a remote site using typical form submits. I was referring to using some client side ajax solution. Sorry for the confusion.
You should follow the way OpenID and other single-sign-on system works. How openID works is your website POSTs some token to openID service and in return gets authentication result. Refer How Does it Work? section here
Yes, you can use a special flash library that supports cross-domain calls: YUI connection manager
Added: not sure about the cookie authentication issue though...
The client cannot post to an external site directly; it's a breach of basic cross-domain security models. The exception is accessing javascript with JSONP. What you describe would require access to a user's cookies for another website, which is impossible as the browser only allows cookie access within the same domain/path.
You would need to use a server-side proxy to make cross-domain requests, but you still cannot access external cookies: http://jquery-howto.blogspot.com/2009/04/cross-domain-ajax-querying-with-jquery.html

Categories