The Source for Java Technology Collaboration
User: Password:



Jayson Falkner's Blog

November 2004 Archives


Blarg #10: I'm confused about keeping proper web application state.

Posted by jfalkner on November 22, 2004 at 08:54 PM | Permalink | Comments (9)

Do you write web applications. Do you know why you should always sychronize access to the session and application scopes but not always the request scope? If not, this should help clear things up.

This is a little user support for my book. Cheers to the readers.


> Hi
> 
> I have read your "Servlets and Java Server Pages - The
> j2ee technology web tier" book, by you and Kevin
> Jones.
> (ISBN 0-321-13649-7)
> 
> I have a question about a particular chapter, on
> Chapter 9 "Managing State in a Web Application". You
> mentioned in 'Protecting Session and Application
> State' subtopic, Listing 9-11, that it is important to
> have synchronized block for the session object, so
> that it is unique for every client access.
> 
> Does it mean for every of my httpservlet doGet()
> service method :-
> 
> public class hello extends HttpServlet {
> 
> public void doGet(HttpServletRequest request,
> HttpServletResponse response) throws .... {
> 
> String value1 = request.getParameter("value1");
> HttpSession session =
> request.setAttribute("setValue1", value1);
> ....
> 
> 
> Does it mean above code is wrong, ie I have to
> sychronised session object, before setting Attribute
> to value1 ?
> 
> Same for getAttribute. Let's say I setAttribute here
> in the servlet. But in another servlet, I getAttribute
> for value1. Does it mean I need to have a synchronised
> block for the session object before i getAttribute() ?
> 
> In your book, listing 9-11, your synchronised block
> has the following :
> 
> synchronised (session) { 
> session.setAttribute("user",user);
> ...}
> 
> For the 'user' variable, can I presume 'User' is a
> actual java class, or it is just to illustrate the
> need to have a unique identifier for this particular
> session ?
> 
> Thanks!

You need to keep in mind what is shared and what is not shared when thinking about state. For each doGet() method invocation a new HttpServletRequest object is made, and you can access this object without fearing that any other thread is concurrently accessing it. However, this changes for the HttpSession object. Two requests from the same user might try to change the same session object. There is only one session object per a user accessing the web app.

The point is. If you are using:

request.setAttribute("setValue1", value1);

You don't need to synchronize. The "request" implicit object is the HttpServletRequest for that doGet() invocation.

But, if you are using:

session.setAttribute("setValue1", value1);

You need to synchronize to the session:

synchronized(session) {
 // whatever code you like
  session.setAttribute("setValue1", value1);
 // whatever other code you like
}

The HttpSession object is shared for every user request. If the user clicks a submit button twice or just makes multiple requests quickly, the web server might have two threads manipulating the HttpSession object at the same time.

Again, the difference is that each doGet() makes a new "request" object, but every doGet() for the same client uses the same "session" object. If you want to keep proper state, you need to synchronize to the shared objects, i.e. "session" but you don't have to worry about the "request" object. If you apply this to the ServletContext object, i.e. "application", you will always want to synchronize it. Every doGet() method, regardless of user, shares the same application object.

Addressing your comments.

> String value1 = request.getParameter("value1");
> HttpSession session =
> request.setAttribute("setValue1", value1);
> ....
> 
> Does it mean above code is wrong, ie I have to
> sychronised session object, before setting Attribute
> to value1 ?

No. Unless I'm missing something the above code isn't doing anything to the session object -- I'm not even sure it is valid code. If you are using setAttribute()/getAttribute() on the request object you don't need to synchronize. But if you used the same methods on the session object, you should synchronize the related code.

> Same for getAttribute. Let's say I setAttribute here
> in the servlet. But in another servlet, I getAttribute
> for value1. Does it mean I need to have a synchronised
> block for the session object before i getAttribute() ?

It depends. If you are using MVC and you are just passing objects between Filters/Servlets used in the same request via the request object, you don't need to synchronize. However, if you are putting items in session scope, e.g. making a shopping cart that tracks user's items across multiple requests, you should synchronize all code that manipulates session scope.

> For the 'user' variable, can I presume 'User' is a
> actual java class, or it is just to illustrate the
> need to have a unique identifier for this particular
> session ?

Oops, this is kind of a bad example. "user" the String is just a string. It would let something like the JSP EL use ${user}. The second argument named user is a reference to a fictitious variable that could represent any Java object.

Cheers,

Jayson Falkner
jayson@jspinsider.com



Blarg #9: Help me make code that is a webapp, uses a DB, and is secure

Posted by jfalkner on November 22, 2004 at 07:25 PM | Permalink | Comments (2)

Here is a reply to a really common question. What are the things I should keep in mind when making a secure website? This particular question was from a person who was considering using Java or Python, but the important stuff really doesn't rely on a particular programming language. If you are green, take a peek. If you know your stuff, fill in what I missed.

You'll note my answer hints at Linux+Java, and I don't say just use J2EE. I'm biased to the free, simple, easy solution. Please feel free to argue something better.

howdy,

it looks like i might be writing some code that involves
 
  - a web-based front-end
  - lots of database action on the back-end
  - a real need to care about security
 
 i'll probably be doing this with someone who's pretty good with Python, 
 but we might be convinced to switch to java.  seems like i ought to pick 
 your brain about this in either case.  any good resources i should start 
 with (i don't know anything that's not obvious about databases or 
 security, for example)?

In general, security isn't too tough, especially if you have local access to the server. Here are the easy fixes:

  • Don't let external ip addresses access your DB. Always admin in person, at the box. Close/firewall the sensitive ports.
  • Don't let root or dbadmin remotely log in to the server. Always require that sort of user to log in locally.
  • Don't ever let users execute SQL commands. Abstract DB access via a simple library.
  • If you don't need full db write access, set up a SQL view that won't let the webapp write/delete parts of the DB that it shouldn't.
  • Tunnel all sensitive web traffic using SSL/TLS. Everything else sends content via plain text. If you are real paranoid, buy a real 509.x certificate so that you don't have to worry about man-in-the-middle hacks.
  • Sandbox the app. Literally with Java. Don't let webapp code read/write to things that it shouldn't. This is a common flaw in most CGI-based apps.
  • Don't use ftp or telnet. Use sftp and ssh if you need to, and never give more read/write access than is needed.
  • Back up frequently and have the server e-mail its remote access and firewall logs to you. Proactively block all the ips that ping your server every second with a login attempt (you'll have quite a few)
  • Don't be lazy.

Doing all this on linux/java is no problem. SSH, SFTP, and firewall/packet filtering comes with linux. All the restrict-root-to-a-local-user tricks are simple SSHD configuration options. Pick up a SQL book or google for help with db management, it is old hat. Java/Jakarta Tomcat will solve all the webapp/SSL/TLS/db access issues.

Outside of Linux/Java. Most all of the mentioned software is available for non-windows boxes. Don't use windows. As for python, if you are happpy with the db access libraries and the webapp/CGI libraries you should be fine. If I remember right, python has weak HTTP/SSL/TLS support, but Apache can easily make up for that.

You should be able to pair "howto" with any of software names I mentioned and google will turn up plenty of guides.

Good Luck!

Jayson Falkner
jayson@jspinsider.com





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds