Re: [OT-ish] Session refresh philosophy

2002-02-21 Thread dom

> 
> You've addressed the issue of someone submitting a form with altered fields
> to attack the server, and pointed out some more advantages, but I don't
> think you've addressed the issue of protecting the "hidden" cleartext data
> from others on the client side.

True. But to tackle these concerns, SSL looks like a better approach
to me. If the client doesn't do any math/crypto/secret stuff at all,
an attacker that is on the same subnet can both spy on secrets (egress
passwords or private data, ingress session IDs or cookies) and take
over sessions (just by changing IPs - no need to even hijack TCP
connections since they are short-lived in HTTP) - and then there is
nothing that the victim could do that the attacker cannot. The point
is, secrets pass over the wire in the clear at a moment or another, so
encrypting them for all transfers but the first one only earns a
marginal amount of security.

This is not to say I don't enjoy using the various state storage
mechanisms described in the thread. They are highly useful but I think
that the encryption part of them only addresses problems on the server
side and are useless under certain forms of site design.

-- 
Dominique QUATRAVAUX   Ingénieur développeur sénior
01 44 42 00 35 IDEALX




RE: [OT-ish] Session refresh philosophy

2002-02-20 Thread David Harris


Drew Taylor [mailto:[EMAIL PROTECTED]] wrote:
> I just looked at CGI::EncryptForm and David's module. The thing I like
> right off the bat about C:EF is that you pass a href to encrypt() and get
> back a href from decypt(). Perhaps I missed something, but FormContainer
> takes a string, not a data structure. I prefer the simplicity of just
> worrying about a structure, and not having to worry about converting it to
> a string.

My module, FormContainer, takes arbitrary data structures like hash
references too. You probably didn't see this because I used my own
serializer module called FreezeThawLite instead of Storable. The lack of
documentation of my module may have also been a problem. :-)

I mentioned that a trivial rewrite to use Storable would be required when I
attached the code. Simply replace FreezeThawLight::freeze with
Storable::freeze and FreezeThawLight::thaw with Storable::thaw. :-)

I agree with you that having to manually serialize session data to a string
would be a real pain!

> That said, I like the approach that the two modules use. One just goes an
> extra step to guarantee data security. While looking for full-time
> employment, I've been doing some freelance work, which basically is small
> CGI apps. C:EF looks like it would make my life much easier by ensuring
> consistent state w/ small effort on my part, and take care of any security
> precautions as well. Combine that w/ CGI::Application (after I add TT2
> support :-) ), and my life as a freelance CGI guy just got a whole lot
easier.

See my last message about the security comparisons.

> Thank you to everyone who contributed to this thread. I've gotten all
kinds
> of neat ideas I'll use in future projects!

Good stuff.

David





RE: [OT-ish] Session refresh philosophy

2002-02-20 Thread David Harris


[EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] wrote:
> I can see how your approach adds functionality by performing as expected
if
> the user uses the Back button or opens the app. in more than one browser
> window. The usual objection I've heard to using form fields is the
security
> risk of people changing hidden fields in ways unforseen before submitting
> the form back, or of other people finding confidential data hidden in form
> fields if the user walks away and leaves their browser open, or the web
> page info gets hijacked somehow. Does your module address this, or is this
> yet another tradeoff between security and functionality/convenience?

My module addresses the first concern of an attacker changing the data in
the hidden fields. On encoding, I hash together the encoded data and a
secret to get a security hash. On decoding, I perform the same hashing and
make sure it matches. Without the secret data no one can generate a security
hash for modified data.

My module does not address encryption. It would be trivial to add. It wasn't
a concern with my application.

By note of comparison, it looks like CGI::EncryptForm addresses both the
encryption and non-user-modifiable concerns for the hidden data.

David





RE: [OT-ish] Session refresh philosophy

2002-02-20 Thread David Harris


Perrin Harkins [mailto:[EMAIL PROTECTED]] wrote:
> Okay, I only looked at it briefly and thought it stored the data on the
> client.  Your module is actually more like CGI::EncryptForm I think, but
> yours may make things a bit more transparent.  Maybe you should polish it
up
> for CPAN.

I looked at CGI::EncryptForm. It is used to store data on the client. The
main difference between it and my module is that: (a) it encrypts the data,
while I only prevent users from modifying the data, and (b) it stores the
data in one field, while I store in multiple fields to make double sure that
I don't hit any length restrictions.

> I'm well aware of the page-state vs. browser-state problem.  I was
recently
> bitten by it again when some consultants built a web app for my company
that
> puts the search results in a session keyed on a cookie.  As soon as the
user
> opens two windows, it's absolute mayhem.

I wasn't exactly what to call it and if people would recognize it by name,
so I started writing a short description which just grew. :-)

David





Re: [OT-ish] Session refresh philosophy

2002-02-20 Thread ___cliff rayman___

Rob Nagler wrote:

> [EMAIL PROTECTED] writes:
> > Looking at CGI::EncryptForm that Perrin mentioned, it appears that that
> > module would address this concern by storing client-side in a single
> > encrypted string that gets put in one hidden form variable. That also
> > avoids having to verify more than once.
>
> It is always good to validate the data even if it was encrypted.  It
> is also generally a good idea not to give the user any secrets, even
> if they are encrypted.  In other words, avoid trusting the user.
>
> [EMAIL PROTECTED] writes:
> > No, this just means that input must be validated once again when the
> > last «really, really sure ?» button is depressed. Conceptually, this
> > divides the pages of your site into two categories (not unlike the
> > view vs. controller distinction in Model-View-Controller paradigm for
> > GUIs): those that just interact with the user and do the navigation,
> > and those that actually have side effects such as writing data into your
> > database, sending e-mails, placing orders etc.
>
> It is MVC.  However, instead of thinking of pages, I like to think in
> terms of tasks.  The same task that renders the form also validates
> and executes it. In the case of execution, the result is a redirect
> described by the site's state machine.  A form in our world has four
> states: execute_empty (fill in defaults), execute_ok, execute_other
> (e.g., cancel or sub form), and execute_unwind (coming back from a sub
> form).  All of these paths go through the same task.

please take this as interested and not critical.  i was viewing the source:
http://petshop.bivio.biz/src?s=View.items

and i noticed these lines:

- snip 
])->put(
cellpadding => 2,
cellspacing => 2,
   ),
- snip -

this looks like the presentation layer peeking through.

the petshop site is obviously a demo, and therefore does not have the polished look of
a professional site, which is very understandable.  what i wonder is, could a 
professional
web design team make a polished website without involving the programmers?  what
happens when a cell padding of 3 is more desirable for the design?  it seems to me,
that in all of the technologies i have looked at thus far, that attempt to separate the
presentation
layer from the model/view, the precision and flexibility needed to graphically 
communicate
to the user is more difficult that the standard pagedesign approaches (dreamweaver and 
a little
embperl or other embedded language thrown into the mix) .  phrased another way,
how does bivio or other mvc technology, let web artists design sites as beautiful as
http://www.marthastewart.com or the even more beautiful http://www.genwax.com (cheap 
plug)?


--
___cliff [EMAIL PROTECTED]http://www.genwax.com/





Re: [OT-ish] Session refresh philosophy

2002-02-20 Thread Rob Nagler

[EMAIL PROTECTED] writes:
> Looking at CGI::EncryptForm that Perrin mentioned, it appears that that
> module would address this concern by storing client-side in a single
> encrypted string that gets put in one hidden form variable. That also
> avoids having to verify more than once.

It is always good to validate the data even if it was encrypted.  It
is also generally a good idea not to give the user any secrets, even
if they are encrypted.  In other words, avoid trusting the user.

[EMAIL PROTECTED] writes:
> No, this just means that input must be validated once again when the
> last «really, really sure ?» button is depressed. Conceptually, this
> divides the pages of your site into two categories (not unlike the
> view vs. controller distinction in Model-View-Controller paradigm for
> GUIs): those that just interact with the user and do the navigation,
> and those that actually have side effects such as writing data into your
> database, sending e-mails, placing orders etc.

It is MVC.  However, instead of thinking of pages, I like to think in
terms of tasks.  The same task that renders the form also validates
and executes it. In the case of execution, the result is a redirect
described by the site's state machine.  A form in our world has four
states: execute_empty (fill in defaults), execute_ok, execute_other
(e.g., cancel or sub form), and execute_unwind (coming back from a sub
form).  All of these paths go through the same task.

Rob



Re: [OT-ish] Session refresh philosophy

2002-02-20 Thread Drew Taylor

I just looked at CGI::EncryptForm and David's module. The thing I like 
right off the bat about C:EF is that you pass a href to encrypt() and get 
back a href from decypt(). Perhaps I missed something, but FormContainer 
takes a string, not a data structure. I prefer the simplicity of just 
worrying about a structure, and not having to worry about converting it to 
a string.

That said, I like the approach that the two modules use. One just goes an 
extra step to guarantee data security. While looking for full-time 
employment, I've been doing some freelance work, which basically is small 
CGI apps. C:EF looks like it would make my life much easier by ensuring 
consistent state w/ small effort on my part, and take care of any security 
precautions as well. Combine that w/ CGI::Application (after I add TT2 
support :-) ), and my life as a freelance CGI guy just got a whole lot easier.

Thank you to everyone who contributed to this thread. I've gotten all kinds 
of neat ideas I'll use in future projects!

Drew

At 10:19 AM 2/20/2002 -0500, Perrin Harkins wrote:
> > When I used CGI::SecureState it gave the client a non-versioning (more on
> > that later) key and stored the state information in the filesystem.
>
>Okay, I only looked at it briefly and thought it stored the data on the
>client.  Your module is actually more like CGI::EncryptForm I think, but
>yours may make things a bit more transparent.  Maybe you should polish it up
>for CPAN.
>
>I'm well aware of the page-state vs. browser-state problem.  I was recently
>bitten by it again when some consultants built a web app for my company that
>puts the search results in a session keyed on a cookie.  As soon as the user
>opens two windows, it's absolute mayhem.
>
>- Perrin

Drew Taylor JA[P|m_p|SQL]H
http://www.drewtaylor.com/  Just Another Perl|mod_perl|SQL Hacker
mailto:[EMAIL PROTECTED]  *** God bless America! ***







Re: [OT-ish] Session refresh philosophy

2002-02-20 Thread wsheldah


You've addressed the issue of someone submitting a form with altered fields
to attack the server, and pointed out some more advantages, but I don't
think you've addressed the issue of protecting the "hidden" cleartext data
from others on the client side. I guess that's a matter of how paranoid you
think you need to be, and how confidential is the data you're storing.
Looking at CGI::EncryptForm that Perrin mentioned, it appears that that
module would address this concern by storing client-side in a single
encrypted string that gets put in one hidden form variable. That also
avoids having to verify more than once.

Looks like it might worth be taking another look at this approach next time
I start a new project.

Wes



[EMAIL PROTECTED] on 02/20/2002 11:48:28 AM

Please respond to [EMAIL PROTECTED]

To:   mod_perl Mailing List <[EMAIL PROTECTED]>
cc:
Subject:  Re: [OT-ish] Session refresh philosophy


> The usual objection I've heard to using form fields is the security
> risk of people changing hidden fields in ways unforseen before submitting
> the form back, or of other people finding confidential data hidden in
form
> fields if the user walks away and leaves their browser open, or the web
> page info gets hijacked somehow. Does your module address this, or is
this
> yet another tradeoff between security and functionality/convenience?

No, this just means that input must be validated once again when the
last «really, really sure ?» button is depressed. Conceptually, this
divides the pages of your site into two categories (not unlike the
view vs. controller distinction in Model-View-Controller paradigm for
GUIs): those that just interact with the user and do the navigation,
and those that actually have side effects such as writing data into your
database, sending e-mails, placing orders etc.

Both page types may have form input validation code on the server
side, but in the first case this is just convenience for the user
(warn early and don't say "woops" after 9 pages and 10 minutes of
typing). The latter MUST have validation for security to hold (even if
this means validating twice). This way, changing hidden fields gains
an attacker nothing, since he will be blocked at the final submit
anyway. Doing things this way also has other advantages
e.g. interfacing: one can write automatisms with "wget" or
LWP::UserAgent to trigger actions in the database without any further
programming needed on the server side.

--
Dominique QUATRAVAUX   Ingénieur développeur sénior
01 44 42 00 35 IDEALX










Re: [OT-ish] Session refresh philosophy

2002-02-20 Thread dom

> The usual objection I've heard to using form fields is the security
> risk of people changing hidden fields in ways unforseen before submitting
> the form back, or of other people finding confidential data hidden in form
> fields if the user walks away and leaves their browser open, or the web
> page info gets hijacked somehow. Does your module address this, or is this
> yet another tradeoff between security and functionality/convenience?

No, this just means that input must be validated once again when the
last «really, really sure ?» button is depressed. Conceptually, this
divides the pages of your site into two categories (not unlike the
view vs. controller distinction in Model-View-Controller paradigm for
GUIs): those that just interact with the user and do the navigation,
and those that actually have side effects such as writing data into your
database, sending e-mails, placing orders etc.

Both page types may have form input validation code on the server
side, but in the first case this is just convenience for the user
(warn early and don't say "woops" after 9 pages and 10 minutes of
typing). The latter MUST have validation for security to hold (even if
this means validating twice). This way, changing hidden fields gains
an attacker nothing, since he will be blocked at the final submit
anyway. Doing things this way also has other advantages
e.g. interfacing: one can write automatisms with "wget" or
LWP::UserAgent to trigger actions in the database without any further
programming needed on the server side.

-- 
Dominique QUATRAVAUX   Ingénieur développeur sénior
01 44 42 00 35 IDEALX




RE: [OT-ish] Session refresh philosophy

2002-02-20 Thread wsheldah


I can see how your approach adds functionality by performing as expected if
the user uses the Back button or opens the app. in more than one browser
window. The usual objection I've heard to using form fields is the security
risk of people changing hidden fields in ways unforseen before submitting
the form back, or of other people finding confidential data hidden in form
fields if the user walks away and leaves their browser open, or the web
page info gets hijacked somehow. Does your module address this, or is this
yet another tradeoff between security and functionality/convenience?

Wes Sheldahl



"David Harris" <[EMAIL PROTECTED]> on 02/20/2002 09:50:11 AM

To:   "Perrin Harkins" <[EMAIL PROTECTED]>, "Drew Taylor"
  <[EMAIL PROTECTED]>, "mod_perl Mailing List" <[EMAIL PROTECTED]>
cc:
Subject:  RE: [OT-ish] Session refresh philosophy



Perrin Harkins [mailto:[EMAIL PROTECTED]] wrote:
> > I built and use a module that encodes a session hash into a
> > number of hidden fields with a security MD5 sum.
>
> Sounds a lot like CGI::SecureState.  Have you ever looked at it?


My module doesn't need to store any information in a database or in the
filesystem. The entire state is given to the client in hidden form fields,
and is passed back to the server on the next request.

In addition, CGI::SecureState does not tie the state information to the
*page*. With my module (or any method that stores the *data* in a hidden
form field, not just a non-versioning key), state information is tied to
the
page. Let me explain:







Re: [OT-ish] Session refresh philosophy

2002-02-20 Thread Perrin Harkins

> When I used CGI::SecureState it gave the client a non-versioning (more on
> that later) key and stored the state information in the filesystem.

Okay, I only looked at it briefly and thought it stored the data on the
client.  Your module is actually more like CGI::EncryptForm I think, but
yours may make things a bit more transparent.  Maybe you should polish it up
for CPAN.

I'm well aware of the page-state vs. browser-state problem.  I was recently
bitten by it again when some consultants built a web app for my company that
puts the search results in a session keyed on a cookie.  As soon as the user
opens two windows, it's absolute mayhem.

- Perrin




RE: [OT-ish] Session refresh philosophy

2002-02-20 Thread David Harris


Hans Juergen von Lengerke [mailto:[EMAIL PROTECTED]] wrote:
> David Harris <[EMAIL PROTECTED]> on Feb 19, 2002:
> > The encoded information is [...] split into reasonable length hidden
> > fields.
>
> Why not put everything in one field? Are there restrictions? Does it
> make a difference when using POST?

The POST encoding dose not have a limit on data length. Heck, people use
 tags with huge amounts of content all the time.

However, I didn't feel comfortable assuming that the HTML parser used by the
browser could easily parse a potentially 20kb attribute. Basically, I didn't
want to make my production application a stress-test for my user's browsers.
:-)

It was easy to break the data up into multiple hidden fields, because Base64
encoding breaks the data into multiple lines by default. I simply encoded
each line in one hidden field.

I would *NOT* use my module with a GET form if you expect any size of data.
I've seen the query string get truncated at some arbitrary size limit.

David





Re: [OT-ish] Session refresh philosophy

2002-02-20 Thread Rob Nagler

Hans Juergen von Lengerke writes:
> Why not put everything in one field? Are there restrictions? Does it
> make a difference when using POST?

That's what we do.  There doesn't appear to be a restriction with
POST.

For while, we were encoding entire forms in URLs, but the limits got
to us for really large forms.

Rob



RE: [OT-ish] Session refresh philosophy

2002-02-20 Thread David Harris


Perrin Harkins [mailto:[EMAIL PROTECTED]] wrote:
> > I built and use a module that encodes a session hash into a
> > number of hidden fields with a security MD5 sum.
>
> Sounds a lot like CGI::SecureState.  Have you ever looked at it?

I just installed and played with CGI::SecureState (using the example in the
POD) and it is totally different than my module.

When I used CGI::SecureState it gave the client a non-versioning (more on
that later) key and stored the state information in the filesystem.

My module doesn't need to store any information in a database or in the
filesystem. The entire state is given to the client in hidden form fields,
and is passed back to the server on the next request.

In addition, CGI::SecureState does not tie the state information to the
*page*. With my module (or any method that stores the *data* in a hidden
form field, not just a non-versioning key), state information is tied to the
page. Let me explain:

Imagine a multi-step order process where the user works through pages A, B,
C, and D, (which contain forms) then uses the back button to go back to page
B, changes the form values, and submits the form. With CGI::SecureState,
page C will receive the state information stored by page D (that was
intended for use by page E, we presume), instead of the state originally
stored by page B (that was intended for page C). This is because all the
pages share the same key, and old "versions" of the state are overwritten by
the new "versions" and no longer available. When the back button is hit, a
newer version of state may be used where an older version was intended.

With my module, page C always gets the state information stored for it by
page B, since the state is stored in hidden form fields in page B. The
browser is actually storing the state and will always submit that same state
to page C.

(I have mentioned that CGI::SecureState uses a non-versioning key a few
times. A way to make CGI::SecureState tie the state information to the
actual page would be to change the key whenever the state changed, thus
creating a versioning key. The key could be a hash of the state itself. This
potentially means that a huge number of versions of the state would have to
be stored on disk. I think this method would only be helpful if the state is
large and it's not acceptable to pass it back and forth between the client.)

In addition, CGI::SecureState gets fuddled if the user opens a new window
(something I do often) and then starts performing different operations in
each window using the same state key! It has no way of knowing a new windows
exists and generating a new key.

If you just store a customer id, customer name, and other rarely changing
information in the state, these concerns may not matter to you. If you break
a long form or order process into multiple pages, gathering new information
on each page and storing it in the state so that you can process the order
at the end, then this is a likely problem.

David





Re: [OT-ish] Session refresh philosophy

2002-02-20 Thread Hans Juergen von Lengerke

David Harris <[EMAIL PROTECTED]> on Feb 19, 2002:

> The encoded information is [...] split into reasonable length hidden
> fields.

Why not put everything in one field? Are there restrictions? Does it
make a difference when using POST?

Hans




Re: [OT-ish] Session refresh philosophy

2002-02-19 Thread Perrin Harkins

> I built and use a module that encodes a session hash into a number of
hidden
> fields with a security MD5 sum.

Sounds a lot like CGI::SecureState.  Have you ever looked at it?

- Perrin




RE: [OT-ish] Session refresh philosophy

2002-02-19 Thread David Harris


David Harris [[EMAIL PROTECTED]] wrote:
[snip]
> I've attached some code. To use the code, you'll have to replace the
> module FreezeThawLite with Storable. Also, beware the \r\n newlines.
> (I pulled this out of CVS on my windows desktop.)

I forgot to actually attach the code

David




package Fusion::FormContainer;
use strict;

use Digest::MD5 ();
use MIME::Base64 ();
use FreezeThawLight ();
use Compress::Zlib ();

use Carp;

# this respresents a securty hole if we open-source this module.. the securtiy string
# needs to be passed as confguration at that point somehow.

sub _create_security_string
{
my $string = shift;

my $secret = add($string);
$ctx->add($secret);
return $ctx->hexdigest;
}

sub encode
{
my $info = shift;
my $prefix = shift;

my $string = 
MIME::Base64::encode(Compress::Zlib::compress(FreezeThawLight::freeze($info)));
$string =~ s/\n$//;

my @array;

push @array, ("${prefix}_fc_security", _create_security_string($string));

my $part_number = 0;
foreach my $part ( split "\n", $string ) {
my $part_number_string = sprintf("%.3d", $part_number);
push @array, ("${prefix}_fc_part$part_number_string", $part);
$part_number++;
}

if ( wantarray ) {
return @array;
} else {
my $html;
while ( @array ) {
my $name = shift(@array);
my $value = shift(@array);
$html .= <
EOT
}
return $html;
}
}

sub decode
{
my $apr = shift;
my $prefix = shift;

my $security = $apr->param("${prefix}_fc_security");

my @string_parts;
my $part_number = 0;
while ( 1 ) {
my $part_number_string = sprintf("%.3d", $part_number);
my $part = $apr->param("${prefix}_fc_part$part_number_string");
last if ( $part eq "" );
push @string_parts, $part;
$part_number++;
}
my $string = join "\n", @string_parts;

croak "tampered or malformed FormContainer: securty string and string don't 
match"
if ( _create_security_string($string) ne $security );

return 
FreezeThawLight::thaw(Compress::Zlib::uncompress(MIME::Base64::decode($string)));
}

1;



RE: [OT-ish] Session refresh philosophy

2002-02-19 Thread David Harris


Drew Taylor [mailto:[EMAIL PROTECTED]]:
> And that is what I am doing for a small project I'm working on now. In my
> case, I'm not sure about the capabilities of the remote server, and I know
> for sure that I don't have a database available, so session information is
> saved via hidden form fields. It's primitive, but was actually a bit of a
> challenge to make sure a (unused) hidden field and a visible form element
> don't appear in the same . Not my first choice, but it definitely
works.

I built and use a module that encodes a session hash into a number of hidden
fields with a security MD5 sum. The encoded information is serialized,
gzipped, Base64 encoded, and then split into reasonable length hidden
fields. It looks like this:





This way, you don't have to worry about creating hidden form fields in your
templates for every variable you need to encode. In your perl, simply call
the session encode and decode methods. You are also assured that nobody
messed with the data.

You can easily "pass" arbitrarily complex session information from one page
to another without using a database, and the session info is truly tied to
the *page*. Use of the back button, therefore, doesn't break anything.

I've attached some code. To use the code, you'll have to replace the module
FreezeThawLite with Storable. Also, beware the \r\n newlines. (I pulled this
out of CVS on my windows desktop.)

HTH.

David





Re: [OT-ish] Session refresh philosophy

2002-02-19 Thread Milo Hyson

On Tuesday 19 February 2002 02:55 pm, Perrin Harkins wrote:
> Incidentally, this is mostly the same thing as what Jeffrey Baker mentioned
> a few days ago about storing state entirely inside a cookie with a message
> digest.  The only difference is that by sticking it in a form element
> you're attaching it to a specific page.

That's not a bad idea. I guess if you're paranoid about snooping you could 
always encrypt the cookie.

-- 
Milo Hyson
CyberLife Labs, LLC



Re: [OT-ish] Session refresh philosophy

2002-02-19 Thread Drew Taylor

At 05:55 PM 2/19/2002 -0500, Perrin Harkins wrote:
>Incidentally, this is mostly the same thing as what Jeffrey Baker mentioned
>a few days ago about storing state entirely inside a cookie with a message
>digest.  The only difference is that by sticking it in a form element you're
>attaching it to a specific page.

True. I was very intrigued by his approach, and might use something like 
that to increase the security of my app by verifying the hidden form field 
contents. I suppose I could follow his approach, but the amount of data I 
need to store could possibly overwhelm the 4KB cookie limit. In this case, 
simple was better - simple application, simple session. And I know I can 
count on every browser implementing forms. :-)

Drew


Drew Taylor JA[P|m_p|SQL]H
http://www.drewtaylor.com/  Just Another Perl|mod_perl|SQL Hacker
mailto:[EMAIL PROTECTED]  *** God bless America! ***







Re: [OT-ish] Session refresh philosophy

2002-02-19 Thread Perrin Harkins

> And that is what I am doing for a small project I'm working on now. In my
> case, I'm not sure about the capabilities of the remote server, and I know
> for sure that I don't have a database available, so session information is
> saved via hidden form fields. It's primitive, but was actually a bit of a
> challenge to make sure a (unused) hidden field and a visible form element
> don't appear in the same . Not my first choice, but it definitely
works.

Incidentally, this is mostly the same thing as what Jeffrey Baker mentioned
a few days ago about storing state entirely inside a cookie with a message
digest.  The only difference is that by sticking it in a form element you're
attaching it to a specific page.

- Perrin




Re: [OT-ish] Session refresh philosophy

2002-02-19 Thread Drew Taylor

And that is what I am doing for a small project I'm working on now. In my 
case, I'm not sure about the capabilities of the remote server, and I know 
for sure that I don't have a database available, so session information is 
saved via hidden form fields. It's primitive, but was actually a bit of a 
challenge to make sure a (unused) hidden field and a visible form element 
don't appear in the same . Not my first choice, but it definitely works.

Drew

At 11:42 AM 2/19/2002 +, Ged Haywood wrote:
>Hi there,
>
>On Mon, 18 Feb 2002, Milo Hyson wrote:
>
> > maybe I'm just approaching the problem incorrectly. If one is doing a
> > shopping-cart-style application (whereby someone selects/configures 
> multiple
> > items before they're ultimately committed to a database) how else would 
> you
> > do it? There has to be some semi-persistent (i.e. inter-request) data 
> where
> > selections are stored before they're confirmed.
>
>You can for example send a hidden  object back and forth between
>your Client and the app.

Drew Taylor JA[P|m_p|SQL]H
http://www.drewtaylor.com/  Just Another Perl|mod_perl|SQL Hacker
mailto:[EMAIL PROTECTED]  *** God bless America! ***







Re: Session refresh philosophy

2002-02-19 Thread Rob Nagler

Perrin Harkins writes:
> Actually, even this stuff could be put into a normalized "sessions" table
> rather than serialized to a blob with Storable.  It just means more work if
> you ever change what's stored in the session.

This is a tough question.  If you store it in a blob, you can't query
it with an ad hoc SQL query.  If you store it in a table, you have to
deal with data evolution.  On the whole, I vote for tables over blobs.
My reasoning is that you have to deal with data evolution anyway.  We
have had about 200 schema changes in the last two years, and very few
of them have had anything to do with user/visitor state.

Rob



Re: Session refresh philosophy

2002-02-19 Thread Perrin Harkins

> In that the general idea of expiration is to discard
> information that hasn't been accessed in a while, some feel that updating
the
> timestamp is best done during both loading and storing.

If you don't always store the session (Apache::Session doesn't store unless
you modify data in the session) then you have to update the timestamp on
load to be accurate.  If you want to be frugal, you might make the store
operation update the timestamp, and then install a cleanup handler that will
update the timestamp only if the session was not stored.

- Perrin




Re: Session refresh philosophy

2002-02-19 Thread Perrin Harkins

> As I understand it, the session data is "state" which is committed to
> the database on each request (possibly).  It would seem to me that
> instead of denormalizing the state into a separate session table, you
> should just store it in a normal table.

The typical breakdown I use for this is to put simple state information that
connects this browser to long-term data in the session, and everything else
in normal database tables.  So, I put the user's ID (if this session belongs
to an identified user), a flag telling whether or not this user has given a
secure login so far in this session, and not much else in the session.

Actually, even this stuff could be put into a normalized "sessions" table
rather than serialized to a blob with Storable.  It just means more work if
you ever change what's stored in the session.

- Perrin




Re: Session refresh philosophy

2002-02-19 Thread Rob Nagler

Milo Hyson writes:
> shopping-cart-style application (whereby someone selects/configures multiple 
> items before they're ultimately committed to a database) how else would you 
> do it? There has to be some semi-persistent (i.e. inter-request) data where 
> selections are stored before they're confirmed.

As I understand it, the session data is "state" which is committed to
the database on each request (possibly).  It would seem to me that
instead of denomalizing the state into a separate session table, you
should just store it in a normal table.  If the data needs to be
expired, then it can be time stamped when it is written.

The point is that it's always simpler to use the existing tables
directly rather than making a copy and storing it in the database
somewhere else.  This usually reduces the code by half or more,
because you don't have to worry about making the copy in the first
place.  Simpler code is more reliable and usually runs faster.

To me, sessions are negativist.  My expectation is that users will end
up clicking OK (making the purchase).  If that is the case, you are
much better off putting the data were belongs right from start.  You
may bind it to an ephemeral entity, such as a shopping cart, but when
the order is complete the only thing you have to do is free the cart
and replace it with an order.  The items, amounts, and special
considerations have already been stored.

If most of your users are filling shopping baskets and walking away
from them, it may be a problem with the software.  Checkout
http://www.useit.com for some ideas on how to improve the ratio.

Often you can avoid any server side persistence by using hidden fields
in the forms.  We use this technique extensively, and we have
encapsulated it so that it is easy to use.  For example, you might
have a sub form which asks the user to fill in an address.  When the
user clicks on the "fill in address" button, the server squirrels away
the context of the current form in the hidden fields of the address
form.  When the user clicks OK on the address form, the fields are
stuffed back into the original form including the new address.

If you have a performance problem, solve it when you can measure it.
Sessions can mitigate performance problems, but so can intelligent
caching, which avoids statefulness in the client-server protocol.

Rob

P.S. For sample sessionless sites, visit http://www.bivio.com and
 http://petshop.bivio.biz (which runs on a 3 year old 300mhz box
 running Apache and Postgres).



Re: [OT-ish] Session refresh philosophy

2002-02-19 Thread Ged Haywood

Hi there,

On Mon, 18 Feb 2002, Milo Hyson wrote:

> maybe I'm just approaching the problem incorrectly. If one is doing a 
> shopping-cart-style application (whereby someone selects/configures multiple 
> items before they're ultimately committed to a database) how else would you 
> do it? There has to be some semi-persistent (i.e. inter-request) data where 
> selections are stored before they're confirmed.

You can for example send a hidden  object back and forth between
your Client and the app.

73,
Ged.




Re: Session refresh philosophy

2002-02-18 Thread Milo Hyson

On Monday 18 February 2002 07:29 pm, Rob Nagler wrote:
> I may be asking the wrong question: is there a need for sessions?
> This seems like a lot of work when, for most applications, sessions
> are unnecessary.

I don't see how they could be unnecessary for what we're doing. Then again, 
maybe I'm just approaching the problem incorrectly. If one is doing a 
shopping-cart-style application (whereby someone selects/configures multiple 
items before they're ultimately committed to a database) how else would you 
do it? There has to be some semi-persistent (i.e. inter-request) data where 
selections are stored before they're confirmed.

-- 
Milo Hyson
CyberLife Labs, LLC



Re: Session refresh philosophy

2002-02-18 Thread Rob Nagler

Milo Hyson writes:
> 1) A fix-up handler is called to extract the session ID from a cookie. 
[snip]
> 1a) If for some reason no session was found (e.g. no cookie) a new one is 
[snip]
> 2) During content-generation, the application obtains the session reference 
[snip]
> 3) A clean-up handler is called to re-serialize the session and stick it back

I may be asking the wrong question: is there a need for sessions?
This seems like a lot of work when, for most applications, sessions
are unnecessary.

Rob



Session refresh philosophy

2002-02-18 Thread Milo Hyson

Like my previous question on object caching, this one is potentially a matter 
of style as well. When it comes to implementing expirations on session data, 
I've encountered two schools of thought on when is best to refresh the 
timestamp/expiration. In that the general idea of expiration is to discard 
information that hasn't been accessed in a while, some feel that updating the 
timestamp is best done during both loading and storing. After all, both are 
considered accessing the data. However, taking into account the general 
pattern of HTTP request processing, I feel that updating only during storage 
is best, especially when using a database for persistence.

Suppose one has a SQL table for saving session data. When a request comes in, 
the session is loaded and its expiration is examined. Assuming the session is 
still valid, one could issue another statement to the database to refresh the 
session's expiration time. That's two database ops before the session is even 
used. If you count the one at the end for storing the session back in the 
database it's a total of three per request. My feeling is that if you're 
going to be writing the session back within (hopefully) a fraction of a 
second anyway, you might as well wait until then to refresh the time-out.

The project I'm working on requires that I design a custom application 
platform for current and future projects. My proposed solution to the session 
management problem is as follows:

1) A fix-up handler is called to extract the session ID from a cookie. 
Assuming a valid ID was found, the session is loaded, de-serialized and 
checked for expiration. If all is well, the a reference to the session is 
stored in pnotes for use by the application.

1a) If for some reason no session was found (e.g. no cookie) a new one is 
created and a new cookie is stuffed in the outgoing headers.

2) During content-generation, the application obtains the session reference 
from pnotes and uses it as necessary.

3) A clean-up handler is called to re-serialize the session and stick it back 
in persistent storage (updating the expiration in the process). The handler 
of course does nothing if the application destroyed the session in step 2.

I'm still fairly new to mod_perl and haven't fully taken apart all of the 
various application servers out there to see how they do it. I would still 
appreciate any feedback anyone may have on the above.

Thanks in advance.

-- 
Milo Hyson
CyberLife Labs, LLC