Search code examples
lift

Form-related problems


I am new to Lift and I am thinking whether I should investigate it more closely and start using it as my main platform for the web development. However I have few "fears" which I would be happy to be dispelled first.

Security

Assume that I have the following snippet that generates a form. There are several fields and the user is allowed to edit just some of them.

def form(in : NodeSeq): NodeSeq = {
  val data = Data.get(...)
  <lift:children>
    Element 1: { textIf(data.el1, data.el1(_), isEditable("el1")) }<br />
    Element 2: { textIf(data.el2, data.el2(_), isEditable("el2")) }<br />
    Element 3: { textIf(data.el3, data.el3(_), isEditable("el3")) }<br />
    { button("Save", () => data.save) }
  </lift:children>
}

def textIf(label: String, handler: String => Any, editable: Boolean): NodeSeq =
  if (editable) text(label, handler) else Text(label)

Am I right that there is no vulnerability that would allow a user to change a value of some field even though the isEditable method assigned to that field evaluates to false?

Performance

What is the best approach to form processing in Lift? I really like the way of defining anonymous functions as handlers for every field - however how does it scale? I guess that for every handler a function is added to the session with its closure and it stays there until the form is posted back. Doesn't it introduce some potential performance issue when it comes to a service under high loads (let's say 200 requests per second)? And when do these handlers get freed (if the form isn't resubmitted and the user either closes the browser or navigate to another page)?

Thank you!


Solution

  • With regards to security, you are correct. When an input is created, a handler function is generated and stored server-side using a GUID identifier. The function is session specific, and closed over by your code - so it is not accessible by other users and would be hard to replay. In the case of your example, since no input is ever displayed - no function is ever generated, and therefore it would not be possible to change the value if isEditable is false.

    As for performance, on a single machine, Lift performs incredibly well. It does however require session-aware load balancing to scale horizontally, since the handler functions do not easily serialize across machines. One thing to remember is that Lift is incredibly flexible, and you can also create stateless form processing if you need to (albeit, it will not be as secure). I have never seen too much of a memory hit with the applications we have created and deployed. I don't have too many hard stats available, but in this thread, David Pollak mentioned that demo.liftweb.net at the time had 214 open sessions consuming about 100MB of ram (500K/session).

    Also, here is a link to the Lift book's chapter on Scalability, which also has some more info on security.