[Zope] forms: copying objects from request to request

Jim Penny jpenny@universal-fasteners.com
Mon, 28 Jan 2002 14:59:41 -0500


On Mon, Jan 28, 2002 at 08:09:15PM +0100, Joachim Werner wrote:
> Hi!
> 
> > you must use a hidden form in DocumentB to transport your variable x from
> DocumentA to DocumentC.
> 
> The more elegant solution is using sessions for that. Like SmartWizards do
> for example.
> 
> You'd just store the REQUEST variables you'll need with (in DTML)
> 
> <dtml-call "SESSION.set('x', REQUEST.['x']">.
> 
> Hidden forms work fine, but they are a hack. In some cases they even are a
> security risk: Anybody can open your HTML file with a text editor,
> manipulate the hidden form values and post the form.

Well, to my mind, sessions are also "just a hack".  The problem with
sessions is that they require heavier machinery to support, a policy 
(which is certain to be wrong) about when the session is closed, and
a session key, which is as valuable to a determined cracker as the
hidden fields are.

But lets take these one at a time:

1) heavier machinery:
You have to have a per-user repository for sessions.  A user can have
an arbitrary number of sessions open at once (multiple browser windows).
That means the session data can be very large.  And that tends to
require external databases.  External databases and zope play very
nicely together indeed, but it is an additional requirement.

2) policy problems:
Each use can have an arbitrary number of sessions open.  HTTP does not
signal when a session should be closed, sessions are thus held in a
frozen, and often useless state if a user abandons a session without
logging out.  This gives you one of two choices -- to time out a
session after some amount of time, or to delete all sessions on login.
[Logout is more natural, but you have no guarantee that logout will ever
occur (the user may simply leave, or the browser crash, etc.)].
Arbitrary timeouts are guaranteed to hurt someone, some time.  Login is
more interesting, but makes session recovery after a crash more
problematic.

3) Session IDs:
You have to grant a session ID.  How can it be stored?  In hidden data! 
(Or in the functional equivalent of a cookie.)
And unless you are encrypting all traffic, these can be
sniffed while on the network.  This gives a patient attacker plenty of
opportunity to assume a session by simply responding to the request more
quickly than the actual user.  This is something the user is likely to
"see", but, I suspect something the user is not likely to report.
That is, in some sense, sessions reduce to hidden variables.

Look, HTTP is stateless, by design.  Sessions are stateful, by design. 
A stateless and a stateful system are bound to react in odd ways when 
used together, at least sometimes.

Mind you, I am not blindly opposed to sessions; they sometimes make
a great deal of sense, and I use them myself.   If you have a LOT of
data to transfer and several layers of forms, they can make life much
easier, as the data does not have to be remarshalled into each form.

Also, note that it is not hard to protect hidden variables, people just
seldom do.  For example, you could take a secret, concatenate the hidden
values and calculate a SHA signature of this string.  The server sends
the hidden variabls, as usual, and also sends this SHA as an additional
hidden variable.  Now when the server gets the form back, it performs 
the calculation again.  If the returned SHA does not match the newly 
calculated SHA, then the hidden variables have been tampered with and 
should be rejected.

> 
> I saw this once with a form that changed a user's password. It held the user
> roles in a hidden form field. So the user could have just sent the form with
> "Manager" added to the hidden form field to get full system access ...

See above paragraph.

Recap:  use sessions when you have a lot of data to transfer across
forms.  Use hidden variables when you have small amounts to move.
Sessions are often more secure in practice, not because they are
inherently a better idea, but because session authors have often 
thought the problems through.  In either case, if security is a 
concern, the sessionID and/or any hidden variables should be protected 
using a digital signature.  If you use sessions, be sure that you 
understand and document the session expiration policy.

Jim Penny