4

I have a jsp containing a jquery post to a servlet on my tomcat server which creates a HttpServletRequest. I would like to ensure that only my jsp's calls to my servlet are processed and any requests originating from a source other than my jsp are ignored. Is there a guaranteed way to see what is the referring page calling my server? I have read that using request.getHeader("referer") can be spoofed so I know I can't rely on that.

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
Steve
  • 83
  • 1
  • 6

4 Answers4

5

Generate an unique string as token, store it in the session and embed it as a hidden input value in the POST form of the JSP and finally check in the servlet if the token is valid.

Basically:

On session creation (in HttpSessionListener#sessionCreated(), for example):

Set<String> tokens = new HashSet<String>();
event.getSession().setAttribute("tokens", tokens);

On preprocessing of the JSP request (in HttpServlet#doGet(), for example):

String token = UUID.randomUUID().toString();
Set<String> tokens = (Set<String>) request.getSession().getAttribute("tokens");
tokens.add(token);
request.setAttribute("token", token);

On processing the JSP itself:

<input type="hidden" name="token" value="${token}" />

On postprocessing of the form submit (in HttpServlet#doPost(), for example):

String token = request.getParameter("token");
Set<String> tokens = (Set<String>) request.getSession().getAttribute("tokens");

if (!tokens.remove(token)) {
    response.sendError(HttpServletResponse.SC_BAD_REQUEST);
    return;
}

// ...    

I of course assume that your jQuery.post() functions are written in an unobtrusive way as in $.post(form.action, form.serialize(), callback) so that it simulates exactly the normal synchronous request (in other words, your forms works perfectly fine with JS disabled).

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you very much for the response. I must admit I am new to jquery so I'm not sure if this approach will work for my issue. In my jsp I have something like this [code][/code]. So I am not clear on how to pass the token as you described. Thank you. – Steve Jan 03 '12 at 20:47
  • Oh, you're using a servlet as a webservice. This is actually not a "jQuery post" as mentioned in your question. It's just a GET request. When exactly does this get invoked? Only once during page load? Or multiple times on user interaction? – BalusC Jan 04 '12 at 13:51
  • Sorry for the confusion. It actually gets invoked based on a javascript timer (using a setTimeout method in a loop). Every so many seconds the "$.getJSON..." gets called to update a status on the jsp based on a returned json object. – Steve Jan 04 '12 at 21:19
  • You could then maintain the token as a JS variable and send it as request parameter (as another property of the "aMap" which you have there). – BalusC Jan 05 '12 at 13:03
  • Thank you. Is there a way to hide the JS variable from 'view source'? Define the token in the java portion of the jsp and pass it to the JS perhaps? – Steve Jan 05 '12 at 16:48
  • Nothing can be hidden from the response, even not cookies. As long as your site is not sensitive to XSS attacks (which opens possibilities to dynamically extract the needed data for CSRF means), then you don't need to worry about this. XSS attack prevention is rather simple: use `` or `fn:escapeXml()` whenever you redisplay user-controlled data (this includes everything which you extracted from a HTTP request such as parameters (also the ones stored in DB), headers, cookies, etc). See also http://stackoverflow.com/questions/2658922/xss-prevention-in-java/2658941#2658941 – BalusC Jan 05 '12 at 16:49
1

You can create a random cookie for your jsp, then append it to your POST form, and accept only requests with correct cookie value.

Michał Šrajer
  • 30,364
  • 7
  • 62
  • 85
  • This is actually more secure than other mentioned solutions. Upvoting. – Perception Jan 03 '12 at 20:38
  • @Perception: note that the HTTP session is by itself already backed by a "random cookie". – BalusC Jan 04 '12 at 13:52
  • @BalusC - that generally true (some use URL rewriting). My main point is that cookies will be harder to spoof by unauthorized clients than a token embedded in the HTML page. – Perception Jan 04 '12 at 14:20
  • @Perception: if one figures how to spoof a session cookie, then it's as easy to spoof another cookie as well. – BalusC Jan 04 '12 at 14:25
  • @BalusC - true, but you only need to do a 'View Source' to see all hidden input fields. – Perception Jan 04 '12 at 14:30
0

You could render a secure token to your JSP and include it in your Ajax call to the Servlet where you could verify it. This also doesn't guarantee that the Ajax call is made using a browser and your Javascript but it at least requires someone to get the secure token from the JSP before making the call.

A similar concept is recommended to mitigate CSRF.

Josef Pfleger
  • 74,165
  • 16
  • 97
  • 99
0

Just a bit of semantics. Requests are created usually from the browser which displays your JSP. You can not stop another program from requesting your JSP and using whatever information you give them to request again.

You CAN stop another webpage that is being viewed in a user's browser from executing a request to your site. This is called Cross-site request forgery. You can mitigate this scenario.

So depending on what you are trying to prevent, CSRF solutions might work for you. You can find a premade solution from your web server. For example, here is Tomcat's

Daniel Moses
  • 5,872
  • 26
  • 39