Bug 55278 - mod_session's cookie may be empty, is repeated twice
Summary: mod_session's cookie may be empty, is repeated twice
Status: NEW
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_session (show other bugs)
Version: 2.4.10
Hardware: PC All
: P2 normal with 5 votes (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords: PatchAvailable
Depends on: 56098
Blocks:
  Show dependency tree
 
Reported: 2013-07-18 17:17 UTC by Mikhail T.
Modified: 2019-05-17 16:57 UTC (History)
2 users (show)



Attachments
Only save a session, if marked dirty (564 bytes, patch)
2013-07-26 15:10 UTC, Mikhail T.
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mikhail T. 2013-07-18 17:17:09 UTC
We noticed the odd, if not particularly dangerous behavior of mod_session. The relevant configuration is thus:

  <Location />
        Session On
        SessionCookieName       ti2f    path=/

        # This is the file containing users login data
        SessionHeader   -TI-Replace-Session
        SessionCryptoPassphrase ...
        SessionCryptoCipher     aes256
        SessionEnv      on
  </Location>

The response-headers, sent to a cookie-less request look like this:

200 OK
Cache-Control: no-cache
Connection: close
Date: Thu, 18 Jul 2013 17:12:19 GMT
Server: Apache/2.4.4
Content-Type: text/html
Client-Date: Thu, 18 Jul 2013 17:12:19 GMT
Client-Peer: 10.89.8.68:14443
Client-Response-Num: 1
Set-Cookie: ti2f=;Max-Age=0;path=/
Set-Cookie: ti2f=;Max-Age=0;path=/

Note, the identical Set-Cookie header repeated twice. With empty session string and Max-Age of 0...
Comment 1 Graham Leggett 2013-07-22 10:59:57 UTC
Can you clarify which parts are a problem?

The duplication needs to be avoided obviously, however setting the cookie to the empty string and setting the max-age to zero is the intended behaviour to delete any previous cookie that may have lingered. HTTP is stateless, and therefore no assumptions are made about previous state of the cookie.
Comment 2 Mikhail T. 2013-07-22 16:57:52 UTC
I would say, if there was no cookie presented in the request, then it can be assumed, there is nothing lingering, can it not?
Comment 3 Mikhail T. 2013-07-22 17:38:31 UTC
Even more, perhaps... Even if there was a session-cookie already in the browser, if the server-side processing (CGI, script, whatever) did not attempt to modify the session, then there should not be an attempt to reset the cookie.

Absence of the session-overwriting header should not be treated the same as presence of an empty header, in my humble opinion.
Comment 4 Mikhail T. 2013-07-26 15:10:19 UTC
Created attachment 30633 [details]
Only save a session, if marked dirty

Reading the session_output_filter(), it appears, that the ap_session_save() is invoked unconditionally -- regardless of whether the session was dirtied or not. Indeed, in the following test:

% HEAD -H 'Cookie: fooCookie=O+eAXvYAEeKrG12oGlPfTANDHqG59FO/1krx29xnST4C+Tb+gEU7OCmh7edH87xptVCL9sQyyHEujTp4LAWVWxJmHwLmCVZfdDE+A9vZV0oQma95C4A+YgSGPhuRoceK' 'http://example.com/foo/

we always see a new Set-Cookie header in the response -- even though nothing on the server side changes the data in our setup. Indeed, the newly-set cookie always decrypts to the same string as what we've already supplied -- defeating the purpose of the "dirty" flag completely, it seems.

This patch attempts to fix things... The result "works" for our limited scenario where we set the cookie ourselves -- from a PHP script and only use mod_session to decrypt and parse it so it can then be used by mod_auth_form.

But, it seems to be correct in all cases -- ap_session_set will set the dirty flag and so will the processing of the SessionHeader now. There is no need to rewrite the session in any other case, is there?
Comment 5 email_apache.org 2013-11-15 12:16:41 UTC
I can confirm this behaviour, including the steady renewal of of the session key for:

Apache 2.4.6 and mod_session_db.

My config:

...

DBDriver sqlite3
DBDParams "/apache/db/db.db"

DBDPrepareSQL "delete from session where key = %s" deletesession
DBDPrepareSQL "update session set value = %s, expiry = %lld where key = %s" updatesession
DBDPrepareSQL "insert into session (value, expiry, key) values (%s, %lld, %s)" insertsession
DBDPrepareSQL "select value from session where key = %s and (expiry = 0 or expiry > %lld)" selectsession

DBDPrepareSQL "delete from session where expiry != 0 and expiry < %lld" cleansession

<VirtualHost *:80>
   	ServerName vfolin.pnet.ch

        RewriteEngine           On

...

	<Location /secured>
	    <RequireAll>  
    		   Require valid-user
	    </RequireAll>

	    AuthFormProvider file
	    AuthType form
	    AuthName "Reserved Area"
	    Session On

	    # This is the login page
	    ErrorDocument 401 /login-inline.html

	    # This is the file containing users login data
	    AuthUserFile conf/passwd

	    SessionDBDCookieName session path=/
	    SessionHeader X-Replace-Session


      </Location>
Comment 6 Gregory A Lundberg 2014-11-14 03:40:38 UTC
Cannot verify the comments about empty cookie, but can verify that 2.4.10 inserts duplicate cache and cookie headers
Comment 7 alexandrezia 2015-10-11 21:27:39 UTC
I confirm this is happening, I'm having the same issue.

< HTTP/1.1 302 Found
< Server: nginx
< Date: Sun, 11 Oct 2015 19:16:59 GMT
< Content-Type: text/html; charset=iso-8859-1
< Content-Length: 211
< Connection: close
< Set-Cookie: session=;Max-Age=0;path=/
< Location: /login.html
< Cache-Control: no-cache
< Set-Cookie: session=;Max-Age=0;path=/
< Age: 0

Two Set-Cookie  headers.
Anf this is causing auth_form not working,

This bug report is from 2013 and it is still happening!
Comment 8 alexandrezia 2015-10-11 22:57:39 UTC
Qlready tried the patch attached to this page, and my httpd segfaults, had to revert.
httpd-2.4.16
Comment 9 Daniel Kahn Gillmor 2019-05-17 16:56:41 UTC
I'm seeing the same duplicate Set-Cookie header behavior with mod_session on apache 2.4.38-3 (debian unstable) today.  Can the fix for this 6-year-old issue get applied?  or if it's wrong, can someone at least explain why it's wrong and what would need to be done to fix it?