views:

75

answers:

2

I decided to invest a few hours in trying to secure my site with SSL. Got the server running alright but have hit a wall with my PHP $_SESSION. I understand the issue of passing session ids between HTTP and HTTPS, but that's not happening here (I think). The convoluted session sequence goes something like this:

login.html:

<form action="https://www.mydomain.com/login.php"&gt;

login.php:

if login details correct {
   session_set_cookie_params(3600,'/','mydomain.com',true);
   session_start();
   $_SESSION['...
   session_commmit

At this point, login.js (which manages the dialog AJAX-style) will redirect to http://www.mydomain.com/desktop.html. The JS code backing the HTML then fires

$.ajax({ url: "https://www.mydomain.com/lib/mySQL/mySQL.php", ... });

mySQL.php:

if (!isset($_COOKIE['PHPSESSID'])) {
   throw wobbly

Before I switched to HTTPS, this sequence was working just fine across all browsers; with HTTPS it throws a wobbly across all browsers :( I can confirm (from looking at the Cookie data) that Firefox records a cookie like so:

mydomain.com
Name: PHPSESSID
Content: gobbledygook
Domain: .mydomain.com
Path: /
Send For: Encrypyed connections only.
Expires:  in 1hr.

Everything appears as per the book. Do you have any suggestions as to what's going on?

Thanks.

PS: I did not use session_set_cookie_params before I stumbled upon a post on SO in researching this problem, suggesting that I should. That is, before I set secure=true Firefox would "Send For" any connections, and that did not work either.

EDIT: I observe another detail. I expect that on the Net panel in Firebug my AJAX requests show up as "POST https://www.mydomain.com/lib/mySQL/mySQL.php" and I will be able to select the POST rider and see what went across. I don't get this for the failed request. Weirdly, Firebug display "OPTIONS https://www.mydomain.com/lib/mySQL/mySQL.php" in red and no POST rider.

A: 

That OPTIONS header is sent as a check if Cross Site HTTP Requests are allowed.

https and http are distinct sites, and is subject to the Same Origin Policy. The link above explains everything.

And another article about cross-site XMLHTTPRequest (Google cache)

Lekensteyn
Thanks. I read the SOP after re-reading the jQuery docs. I also came across the concept of document.domain. Whatever I assigned, I always got a "Permission denied" x-domain error in Firebug. I do not get this error when I don't tinker with document.domain. It's weird. The error message that Firebug report (also red) on the OPTIONS line *IS MY OWN MESSAGE* (ie "wobbly"). That is, my PHP script did run. Normally, however, my "wobbly" comes back via the response header. It doesn't seem to do here. From what little I can see of the handshake, it really seems I am sending no cookies.
Ollie2893
So it would appear that my AJAX access is granted but that cookies are suppressed. It smacks a little of "httpOnly" but I tried setting that to False explicitly - no joy. What I cannot understand is that this session cookie actually ORIGINATED on the same HTTPS domain which I am trying to return it to. Arguably, it should not be send to the HTTP domain. In fact, I am trying to say as much by setting "secure=true".
Ollie2893
Just read through your 1st link and that has me worried. FF3.5 isn't that old so many older browser will not support any efforts to clear my access request. The way to work around this then may be to give up on session cookies and switch to passing a sessionID around through code? I have never been comfortable that my sessionIDs to date have survived a single session by virtue of the cookie. Might kill two birds with one stone?
Ollie2893
...which doesn't work either because somewhere in the hand-over from https:login.php to http:desktop.html (or, probably, .php) the sessionID would have to be url-encoded and be unencrypted - a major security flaw.
Ollie2893
A: 

Ok, Lekensteyn has steered me in the right direction, although his references are more fatalistic - from a client-side programmer's perspective - than need be: in the AJAX world the answer to this particular conundrum goes by the acronym of JSONP. And should you find yourself in the same pickle, then here is the trivial jQuery solution:

In your $.ajax call:-

(1)  Set "dataType" to "jsonp"
(2)  Set "type" to "GET".  (The rest of my app is defaulted to POST.  The jQuery code  suggests that POST is supported.  But when I try POST, I get another "Permission denied" from Firefox' OPTIONS header.)
(3)  Where my PHP script would formerly reply

        echo json_encode($data);

     it must now go

        echo $_REQUEST['callback'].'('.json_encode($data).')'

     which effectively formats a function call with $data being the one and only parameter to the function.
(4)  Set "url" to "https://www.mydomain.com/lib/mySQL/mySQL.php"

Works a treat. The GET format's a bit ugly but hey-hoh. I have left my PHPSESSID cookie at "secure=true" so it should only travel across encrypted hand-shakes.

PS: Apols for the awful formatting. One day I am sure to figure out how to format my posts better on this forum.

Ollie2893