[BUG/PATCH] cgi/session.rb

A

Ara.T.Howard

the following program with fail both the way it is, and using the commented
section:


~ > cat a.cgi
#! /usr/local/bin/ruby

require 'cgi'
require 'cgi/session'

cgi = CGI::new

database_manager = CGI::Session::FileStore

session =
=begin
begin
s = CGI::Session::new cgi, 'database_manager' => database_manager, 'new_session' => false
s.delete
s
rescue ArgumentError
CGI::Session::new cgi, 'database_manager' => database_manager, 'new_session' => true
end
=end
CGI::Session::new cgi, 'database_manager' => database_manager

session.close

this_time = Time::now
last_time = session['last_time'] || this_time
session['last_time'] = this_time
session.close

content = ''
content << "<hr> THIS_TIME @ <b>#{ this_time }</b> <hr>"
content << "<hr> LAST_TIME @ <b>#{ last_time }</b> <hr>"

cgi.out{ content }


in either case a new session is __always__ created. the docs say:

...
# A CGI::Session instance is created from a CGI object. By default,
# this CGI::Session instance will start a new session if none currently
# exists, or continue the current session for this client if one does
# exist. The +new_session+ option can be used to either always or
# never create a new session. See #new() for more details.
...

so there is no way to re-use a session attm. this seems serious. i think this
patch addresses the issue:


[ahoward@localhost build/ruby-1.8.2/lib/] diff -u -b -B cgi/session.rb.org cgi/session.rb
--- cgi/session.rb.org 2005-09-13 20:52:14.000000000 -0600
+++ cgi/session.rb 2005-09-13 20:53:32.000000000 -0600
@@ -244,7 +244,7 @@
# end
#
def initialize(request, option={})
- @new_session = false
+ @new_session = nil
session_key = option['session_key'] || '_session_id'
session_id = option['session_id']
unless session_id
@@ -381,10 +381,11 @@
md5 = Digest::MD5.hexdigest(id)[0,16]
@path = dir+"/"+prefix+md5+suffix
unless File::exist? @path
- unless session.new_session
+ unless session.new_session.nil?
raise CGI::Session::NoSession, "uninitialized session"
end
@hash = {}
+ update
end
end


and, indeed, with the change the following works as expected/doccumented:

#! /usr/local/bin/ruby
require 'cgi'
require './cgi/session'

cgi = CGI::new
content = ''
database_manager = CGI::Session::FileStore
this_time = Time::now

begin
session = CGI::Session::new cgi, 'database_manager' => database_manager
last_time = session['last_time'] || this_time
session['last_time'] = this_time
session.close

content << "<hr> THIS_TIME @ <b>#{ this_time }</b> <hr>"
content << "<hr> LAST_TIME @ <b>#{ last_time }</b> <hr>"
rescue Exception => e
m, c, b = e.message, e.class, e.backtrace.join("\n")
content << "<pre>#{ m } (#{ c })\n#{ b }</pre>"
end
cgi.out{ content }


hopefully this hasn't already been fixed - i searched for a while....

regards.


-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| Your life dwells amoung the causes of death
| Like a lamp standing in a strong breeze. --Nagarjuna
===============================================================================
 
A

Ara.T.Howard

On Wed, 14 Sep 2005, Ara.T.Howard wrote:


CGI::Session::MemoryStore and CGI::Session::pStore suffer from same issue...
updated patches (in the right order this time):


--- ./cgi/session.rb.org 2005-09-13 20:52:14.000000000 -0600
+++ ./cgi/session.rb 2005-09-13 21:13:22.000000000 -0600
@@ -244,7 +244,7 @@
# end
#
def initialize(request, option={})
- @new_session = false
+ @new_session = nil
session_key = option['session_key'] || '_session_id'
session_id = option['session_id']
unless session_id
@@ -381,10 +381,11 @@
md5 = Digest::MD5.hexdigest(id)[0,16]
@path = dir+"/"+prefix+md5+suffix
unless File::exist? @path
- unless session.new_session
+ unless session.new_session.nil?
raise CGI::Session::NoSession, "uninitialized session"
end
@hash = {}
+ update
end
end

@@ -451,7 +452,7 @@
def initialize(session, option=nil)
@session_id = session.session_id
unless GLOBAL_HASH_TABLE.key?(@session_id)
- unless session.new_session
+ unless session.new_session.nil?
raise CGI::Session::NoSession, "uninitialized session"
end
GLOBAL_HASH_TABLE[@session_id] = {}




--- ./cgi/session/pstore.rb.org 2005-09-13 21:07:52.000000000 -0600
+++ ./cgi/session/pstore.rb 2005-09-13 21:18:21.000000000 -0600
@@ -9,7 +9,7 @@
# persistent of session data on top of the pstore library. See
# cgi/session.rb for more details on session storage managers.

-require 'cgi/session'
+require './cgi/session'
require 'pstore'

class CGI
@@ -62,7 +62,7 @@
path = dir+"/"+prefix+md5
path.untaint
unless File::exist?(path)
- unless session.new_session
+ unless session.new_session.nil?
raise CGI::Session::NoSession, "uninitialized session"
end
@hash = {}


now i'm noticing that the create of session is not atomic... but that's for
another day.

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| Your life dwells amoung the causes of death
| Like a lamp standing in a strong breeze. --Nagarjuna
===============================================================================
 
N

nobuyoshi nakada

Hi,

At Wed, 14 Sep 2005 12:23:52 +0900,
Ara.T.Howard wrote in [ruby-talk:156036]:
--- ./cgi/session.rb.org 2005-09-13 20:52:14.000000000 -0600
+++ ./cgi/session.rb 2005-09-13 21:13:22.000000000 -0600
@@ -244,7 +244,7 @@
# end
#
def initialize(request, option={})
- @new_session = false
+ @new_session = nil
session_key = option['session_key'] || '_session_id'
session_id = option['session_id']
unless session_id
@@ -381,10 +381,11 @@
md5 = Digest::MD5.hexdigest(id)[0,16]
@path = dir+"/"+prefix+md5+suffix
unless File::exist? @path
- unless session.new_session
+ unless session.new_session.nil?

What does this change?
--- ./cgi/session/pstore.rb.org 2005-09-13 21:07:52.000000000 -0600
+++ ./cgi/session/pstore.rb 2005-09-13 21:18:21.000000000 -0600
@@ -9,7 +9,7 @@
# persistent of session data on top of the pstore library. See
# cgi/session.rb for more details on session storage managers.

-require 'cgi/session'
+require './cgi/session'

Library starts with "./" directs `require' to load from
current working directory. I guess this isn't intended
change.
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: [BUG/PATCH] cgi/session.rb"

|the following program with fail both the way it is, and using the commented
|section:
|
|
| ~ > cat a.cgi
| #! /usr/local/bin/ruby
|
| require 'cgi'
| require 'cgi/session'
|
| cgi = CGI::new
|
| database_manager = CGI::Session::FileStore
|
| session =
| =begin
| begin
| s = CGI::Session::new cgi, 'database_manager' => database_manager, 'new_session' => false
| s.delete
| s
| rescue ArgumentError
| CGI::Session::new cgi, 'database_manager' => database_manager, 'new_session' => true
| end
| =end
| CGI::Session::new cgi, 'database_manager' => database_manager
|
| session.close
|
| this_time = Time::now
| last_time = session['last_time'] || this_time
| session['last_time'] = this_time
| session.close
|
| content = ''
| content << "<hr> THIS_TIME @ <b>#{ this_time }</b> <hr>"
| content << "<hr> LAST_TIME @ <b>#{ last_time }</b> <hr>"
|
| cgi.out{ content }
|
|in either case a new session is __always__ created. the docs say:

Can you explain how it fails? "the way it is" version seems to work
for me. Perhaps you have expected something different from me.

matz.
 
A

Ara.T.Howard

Can you explain how it fails? "the way it is" version seems to work for me.
Perhaps you have expected something different from me.

hmmm. it seems there is more to it than i thought, if i browse this script:

[ahoward@localhost ~]$ cat /var/www/html/acgi/acgi-0.0.0/a.cgi
#! /usr/local/bin/ruby
require 'cgi'
require 'cgi/session'
require 'cgi/session/pstore'

cgi = CGI::new
content = ''
database_manager = CGI::Session::pStore
this_time = Time::now

begin
session = CGI::Session::new cgi, 'database_manager' => database_manager

last_time = session['last_time'] || this_time
session['last_time'] = this_time
session.close

content << "THIS_TIME : #{ this_time }\n"
content << "LAST_TIME : #{ last_time }\n"
content << "SCRIPT_FILENAME : #{ ENV['SCRIPT_FILENAME'] }\n"
content << "SESSION_ID : #{ session.session_id }\n"
rescue Exception => e
m, c, b = e.message, e.class, e.backtrace.join("\n")
content << "#{ m } (#{ c })\n#{ b }"
end
cgi.out('type' => 'text/plain'){ content }


from, for example:

http://localhost/acgi/acgi-0.0.0/a.cgi

i get something like:

THIS_TIME : Tue Sep 13 23:22:41 MDT 2005
LAST_TIME : Tue Sep 13 23:22:41 MDT 2005
SCRIPT_FILENAME : /var/www/html/acgi/acgi-0.0.0/a.cgi
SESSION_ID : 63cdc2ee2c075a914d6943947951b19b

and then refreshing:

THIS_TIME : Tue Sep 13 23:22:59 MDT 2005
LAST_TIME : Tue Sep 13 23:22:59 MDT 2005
SCRIPT_FILENAME : /var/www/html/acgi/acgi-0.0.0/a.cgi
SESSION_ID : c7d7588139a5270da345ee54c89ed88b


but from:

http://fortytwo.merseine.nu/acgi/acgi-0.0.0/a.cgi

i will get:

THIS_TIME : Tue Sep 13 23:23:29 MDT 2005
LAST_TIME : Tue Sep 13 23:22:17 MDT 2005
SCRIPT_FILENAME : /var/www/html/acgi/acgi-0.0.0/a.cgi
SESSION_ID : 814ca3261d52515d3e1d9d608dc80a16

followed by:

THIS_TIME : Tue Sep 13 23:23:50 MDT 2005
LAST_TIME : Tue Sep 13 23:23:29 MDT 2005
SCRIPT_FILENAME : /var/www/html/acgi/acgi-0.0.0/a.cgi
SESSION_ID : 814ca3261d52515d3e1d9d608dc80a16


so in the first the session is re-created each time and in the second not. so
the bug only appears from localhost? or is this not a bug but expected
behaviour? i'm very tired so perhaps it is ;-( is HTTP_COOKIE handled
differently for localhost or something? i looked in the source both nothing
jumped out at me.

adding HTTP_COOKIE info i see, from http://localhost/acgi/acgi-0.0.0/a.cgi

THIS_TIME : Tue Sep 13 23:32:26 MDT 2005
LAST_TIME : Tue Sep 13 23:32:26 MDT 2005
SCRIPT_FILENAME : /var/www/html/acgi/acgi-0.0.0/a.cgi
SESSION_ID : 05d50f3762602883a9a00678495757f5
HTTP_COOKIE : _session_id=5437f16e1ee85101db5a049a8a4a883c; _session_id=d3e4867caa8ea724c6023e91031a2374; _session_id=e17d91c033811031d235e34c1404d188

and from http://fortytwo.merseine.nu/acgi/acgi-0.0.0/a.cgi

THIS_TIME : Tue Sep 13 23:33:36 MDT 2005
LAST_TIME : Tue Sep 13 23:32:22 MDT 2005
SCRIPT_FILENAME : /var/www/html/acgi/acgi-0.0.0/a.cgi
SESSION_ID : 814ca3261d52515d3e1d9d608dc80a16
HTTP_COOKIE : _session_id=814ca3261d52515d3e1d9d608dc80a16; _session_id=6058a54f8ca5d206f7c8c35b0800a406

sorry if this ends up being noise - this simply isn't making sense attm.

btw. i've run this

[ahoward@localhost tmp]$ ls|egrep '^\w{16}$'|xargs -n1 sudo rm -f

out of /tmp many time to clean up old sessions - results are always the same.


-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| Your life dwells amoung the causes of death
| Like a lamp standing in a strong breeze. --Nagarjuna
===============================================================================
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: [BUG/PATCH] cgi/session.rb"

|so in the first the session is re-created each time and in the second not. so
|the bug only appears from localhost? or is this not a bug but expected
|behaviour? i'm very tired so perhaps it is ;-( is HTTP_COOKIE handled
|differently for localhost or something? i looked in the source both nothing
|jumped out at me.

Something must be different. I can't think of anything though.

matz.
 
A

Ara.T.Howard

Hi,

In message "Re: [BUG/PATCH] cgi/session.rb"

|so in the first the session is re-created each time and in the second not. so
|the bug only appears from localhost? or is this not a bug but expected
|behaviour? i'm very tired so perhaps it is ;-( is HTTP_COOKIE handled
|differently for localhost or something? i looked in the source both nothing
|jumped out at me.

Something must be different. I can't think of anything though.

can you reproduce? or is it just me?

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| Your life dwells amoung the causes of death
| Like a lamp standing in a strong breeze. --Nagarjuna
===============================================================================
 
A

Ara.T.Howard

Library starts with "./" directs `require' to load from
current working directory. I guess this isn't intended
change.

that's right - too tired - going to bed ;-(

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| Your life dwells amoung the causes of death
| Like a lamp standing in a strong breeze. --Nagarjuna
===============================================================================
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: [BUG/PATCH] cgi/session.rb"

|> Something must be different. I can't think of anything though.
|
|can you reproduce? or is it just me?

I couldn't. Mine worked fine, even on localhost.

matz.
 
P

Paul

I've seen problems in the past where certain versions of Firefox and
other browsers did not handle cookies for localhost and other domains
without '.' in them. This might be the problem. Check your cookie cache
and see if a cookie is being set.

paul
 
A

Ara.T.Howard

I've seen problems in the past where certain versions of Firefox and other
browsers did not handle cookies for localhost and other domains without '.'
in them. This might be the problem. Check your cookie cache and see if a
cookie is being set.

this is defintely something to do with it. i've been able to duplicate it
twice today in different servers - but still can't pin down exactly which
conditions trigger it. it seems something to do with having multiple
_session_id fields in HTTP_COOKIE and - possibly - having no prior session
storage. it's like some set of conditions sets it up to fail repeatedly but,
if the conditions arise for it to succeed it will continute to succeed... any
thoughts?

cheers.

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| Your life dwells amoung the causes of death
| Like a lamp standing in a strong breeze. --Nagarjuna
===============================================================================
 
A

Ara.T.Howard

Hi,

In message "Re: [BUG/PATCH] cgi/session.rb"

|> Something must be different. I can't think of anything though.
|
|can you reproduce? or is it just me?

I couldn't. Mine worked fine, even on localhost.

o.k. - i finally can reproduce from either localhost or hostname. you can see
problem and solution here

http://fortytwo.merseine.nu/a.cgi

essentially it boils down to Cookie::parse blowing up if multiple comma
separated key=value pairs show up. for example

harp:~ > ruby -r cgi -e "p( CGI::Cookie::parse('k=v0, k=v1') )"
{"k"=>["v0, k=v1"]}

harp:~ > ruby -r cgi -e "p( CGI::Cookie::parse('k=v0; k=v1') )"
{"k"=>["v0"]}

of course the question is what, exactly, the http spec has to say about those
raw cookie string formats. i'm certainly no expert here. however, it seems
that mozilla and firefox (latest) both spit out comma separted k=v pairs under
certain condition so it may be wise to handle this case anyhoe. i'm not sure
my patch it the best way to fix - but it was the least amount of code i could
write to fix the issue.

i did a little googling and comma does, in fact, seem to an acceptable k=v
pair separator:

...
Note: For backward compatibility, the separator in the Cookie header
is semi-colon (;) everywhere. A server SHOULD also accept comma (,)
as the separator between cookie-values for future compatibility.
...

from

http://www.ietf.org/rfc/rfc2965.txt


this

http://wp.netscape.com/newsref/std/cookie_spec.html

also suggests commas may be used as separator since

...
NAME=VALUE
This string is a sequence of characters excluding semi-colon, comma and
white space. If there is a need to place such data in the name or value,
some encoding method such as URL style %XX encoding is recommended,
though no encoding is defined or required.
...

and i would assume the reason semi-colon and comma are disallowed is because
they are reserved as pair separators. it doesn't actually say why it is not
allowed, however.

regards.

ps. i never did figure out how/why my browsers decided to place commas in the
HTTP_COOKIE post, but they (mozilla, firefox) both did at several points
during testing (somehow related to browsing from localhost). the cgi just
emulates this behaviour to show the bug.

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| Your life dwells amoung the causes of death
| Like a lamp standing in a strong breeze. --Nagarjuna
===============================================================================
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top