Code

Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#18128 closed Bug (invalid)

Session key not being created in django.contrib.sessions middleware

Reported by: rhu@… Owned by: nobody
Component: Uncategorized Version: 1.4
Severity: Normal Keywords: session django
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Changes made to https://code.djangoproject.com/ticket/11555 and 864facf5ccc0879dde7e608a3bea3f4bee1d3a57 cause session keys no longer to be created explicitly. Previous session keys work fine but new session keys will not be generated.

i.e.:

https://github.com/rogerhu/django/pull/new/fix_session_middleware

Attachments (0)

Change History (8)

comment:1 Changed 2 years ago by anonymous

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

I met the same problem

comment:2 Changed 2 years ago by rhu@…

comment:3 Changed 2 years ago by aaugustin

  • Resolution set to needsinfo
  • Status changed from new to closed

I'm sorry, but I don't understand your report. Session keys are properly created when you save the session.

Could you provide a test case for our test suite exhibiting the problem?

Version 0, edited 2 years ago by aaugustin (next)

comment:4 Changed 2 years ago by rhu@…

  • Resolution needsinfo deleted
  • Status changed from closed to reopened

We normally log request.session_key on the initial request, so our middleware usually creates the session_key and copies this information to the request object:

request.session_key = request.session.session_key

We later setup a middleware loghandler to capture this session key:

app_format = '%(session_key)s %(message)s'
log_handler.setFormatter(ExceptionFormatter(app_format))

Without explicitly setting it, no session key will be created in Django v1.4. There is no current documentation that mentions this point.
If we have any code on the front-end that does an $.ajax() call:

$.ajax({dataType: 'json',

type: 'POST',
url: '/login/',
data: {'userid': 'userid', 'password' : 'pw'}

);

The problem appears to be that Internet Explorer v8 will not send third-party cookie information (i.e. Facebook cookie) without an accompanying cookie response. Therefore, either the documentation must make this info that session keys must be set explicitly and/or there is a serious defect in assuming that the request session key must be set in order for the server to send back a response.

Without a session cookie being set in the response, the P3P compact policy is not obeyed, and therefore IE8 will not send third-party cookies during Ajax submissions.

(See http://stackoverflow.com/questions/999534/ie-p3p-iframe-and-blocked-cookies-works-until-page-host-page-has-personal-inf for more information.)

The policy specified in a P3P compact policy applies to data stored within all cookies set in the same HTTP response as the compact policy, all cookies set by scripts associated with that HTTP response, and also to data linked to the cookies.

4.1 Referencing compact policies

Any HTTP resource MAY include a P3P compact policy through the P3P response header (cf. Section 2.2.2). If a site is using P3P headers, it SHOULD include this on responses for all appropriate request methods, including HEAD and OPTION requests.

Would appreciate some guidance. I'll try to send more code examples shortly over.

comment:5 Changed 2 years ago by aaugustin

Thanks a lot for the detailed explanation! I have two remarks about it:

1)

Without explicitly setting it, no session key will be created in Django v1.4. There is no current documentation that mentions this point.

To be honest, there isn't any documentation either mentioning that session_key exists before the session is saved.

2)

There is a serious defect in assuming that the request session key must be set in order for the server to send back a response.

Yes, there is. The first time a visitor comes to your site, he doesn't have a request session key. The key is generated when the session is saved, and it's added to the cookies at this point.

As a consequence, I don't understand why you see a relation between request.session.session_key being available in process_request and a cookie being sent in the response, with all the consequences you describe.


The previous behavior was as a bug with security ramifications, as explained in #11555. I'm going to clarify the docs (and add tests) in the context of #13478.

Technically, you're using an internal API, which isn't subject to the backwards compatibility policy. In fact, in SessionMiddleware.process_request, request.session.session_key can be:

  • None for a new visitor (first request on the site)
  • an existing session key for a returning visitor (later requests on the site)
  • a non-existing session key in various cases (expired session, session fixation attack, etc.)

The 1.4 behavior seems correct and logical to me. I understand that you want to capture session_key in SessionMiddleware.process_request, in case you get an exception before the session is saved in SessionMiddleware.process_response. In this case, your code must account for these three possibilities.

comment:6 Changed 2 years ago by aaugustin

In [17911]:

Clarified that Django randomizes session keys. Refs #11555, #13478, #18128.

comment:7 Changed 2 years ago by aaugustin

  • Resolution set to invalid
  • Status changed from reopened to closed

session_key being None in a middelware's process_request is clearly the intended behavior. (Before Django 1.4 you could obtain a session key at this point that wasn't the user's actual session key.
) For this reason I'm going to close the ticket.

I didn't follow entirely the part about AJAX, cookies and P3P. Please reopen if there's something important I missed there.

comment:8 Changed 2 years ago by rhu@…

Nope, turns out the P3P/Ajax/cookie was a separate issue. Please disregard! The docs should definitely be updated though. Appreciate the response!

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.