2

Just a newbie here so please pardon my mistakes.
I'm working on a website using .shtml pages (SSI). I'm trying to include a PHP script into my .shtml page. Up to this point everything is working fine: PHP script gets included and it does what it was intended for. Here is the actual example. There is the home page (index.shtml) including a script called security_check.php with this directive:

<!--#include virtual="includes/security_check.php?idOp=000&idPage=0000" -->

This is the PHP code for security_check.php:

<?php

session_start();

include('config.php');
include('myfunctions.php');
include('security_functions.php');

$idOp                 = $_GET['idOp'];
$idPage               = $_GET['idPage'];
$allowedReferer       = array();

// Connection to the database (defined in myfunctions.php)
$link   = DB_Connect($DBhost, $DBuser, $DBpass, 1, $DBname);

// Check if the PHP session already exists. If not, create one
// (that is insert a record in the DB and returns the id, which
// will be stored in the PHP session variable).
// user ID is 0 because not logged yet
if (!isset($_SESSION['idSess'])) {
    $_SESSION['idUser'] = 0;
    $_SESSION['idSess'] = create_session(); // security_functions.php
}

// Please note that create_session() correctly use $_SESSION['idUser']
// in order to do its work, even if it's not passed as a parameter
// (as it should be: $_SESSION is a superglobal!) and the same goes
// for activity_supervisor().

// Defined in security_functions.php:
// it uses both $_SESSION['idUser'] and $_SESSION['idSess']
activity_supervisor($idPage,$allowedReferer,2,$link);

mysql_close($link);

?>  

At this point, home page is correctly displayed and there is a 'Sign up' button in it, calling sign.shtml. This sign.shtml page include the very same security_check.php script with the exact same include directive already seen above except for the value of idPage parameter which in this case is 0001.

I would expect the script to recognize the PHP session and therefore not creating a new session, but indeed a new session gets created every time.

I already read every other post related to PHP sessions not working and I even tried the solutions proposed there.
- session_start() is written on top of every script because there is just one script
- session.save_path equals to /var/lib/php/session and is writeable by the web server
- I already tried to set session.gc_probability = 0 and restarting the web server (to no avail, so I got back to session.gc_probability = 1)
- I tried with different browsers (namely, Firefox and Chrome) with the same results

So I tried the following test (note those two empty lines BEFORE session_start(): I always space instructions this way to improve readability) creating a simple test.php script

<?php

session_start();

if (!isset($_SESSION['foo'])) {
    $_SESSION['foo'] = 1;
    echo ('Value is '.$_SESSION['foo'].'<br/>');
    echo ('<a href="test.php">Refresh</a>');
}
else {
    $_SESSION['foo']++;
    echo ('Value is '.$_SESSION['foo'].'<br/>');
    echo ('<a href="test.php">Refresh</a>');
}

?>  

Well, believe it or not, every time I hit 'Refresh', the value is incremented, so PHP recognize the session (the test.php script is inside the same domain as the index.shtml and sign.shtml pages).
I even tried to make the PHP script to show a link to a .html file (not .shtml) which then show a link to test.php. It works correctly!

It really seems that the session is not correctly set only when the PHP script is included into the .shtml page, even if I don't see any reason for that. Maybe you know why and, above all, how to circumvent this boring behaviour? Is it a feature? Does it depend on a parameter setting in php.ini?

Final tips:
OS: CentOS 6.3 with 2.6.32-279.el6.x86_64 kernel
Server version: Apache/2.2.15 (Unix)
PHP 5.3.3
Server is mine so I can configure everything, if needed.

Thanks in advance and forgive me for the long post: I tried to make it clear that PHP sessions do work perfectly in every other situation I know of.

Glen Selle
  • 3,966
  • 4
  • 37
  • 59
Ambrosia
  • 61
  • 4
  • TL;DR but... Are you aware that you are inserting the **output** of the PHP script, rather than its code? – Álvaro González Oct 08 '15 at 14:57
  • It would be much simpler if you just used a PHP include instead of SSI for your session script. – Derek Oct 08 '15 at 15:09
  • You can't call 'session_start()' or anything esle which needs to modify the headers simply using mod_include (SSI). Either connect the URL directly to the PHP script or use ESI. – symcbean Oct 08 '15 at 15:10
  • @ÁlvaroG.Vicario Yes, of course, that's exactly what I wanted to do (even if in my example there is no output) – Ambrosia Oct 09 '15 at 08:41
  • @Derek Yeah, it would, and that probably is the way I will solve my problem, but since I don't like to leave things unfinished, I'd like to come up with a solution or an answer. I\m gonna read every answer and test them. – Ambrosia Oct 09 '15 at 09:31
  • @symcbean Let's see if I have understood well. In a page called index.shtml, the server executes the PHP code, this code set a header with the session_id in it, but then that header gets overwritten by the header of the .shtml page? In other words, the last to set the header wins? – Ambrosia Oct 09 '15 at 14:05

1 Answers1

0

I don't think this will work because the SSI will execute the PHP script, and then send out its output to the web server. You would need some way of rewriting URLs so that they do not rely on cookies, since cookies get "eaten" before the server gets to send them to the browser.

Try using

ini_set("session.use_cookies",0);
ini_set("session.use_trans_sid",1);

and then you'll need to send the SID in the outgoing URLs (and on POST pages, too). See this answer for example.

Specifically, you need to redirect the user not to sign.shtml but to something like

$sidkey = session_name();
$sidval = session_id();
print "sign up: <a href=\"sign.shtml?{$sidkey}={$sidval}\">here</a>";

and include this in the SSI output.

UPDATE: the root of the problem is that the SSI cannot create a session (cannot send anything but plain HTML. Sessions that use cookies rely on headers, not HTML only). But if you create the session with a PHP script launched outside SSI, that is able to set a cookie, from that point onwards all PHP scripts (whether SSI or not) are able to read the cookie and therefore will be able to access and modify the session (which is a file/memory/Redis/other on the server identified by the session cookie's value).

You can check whether a cookie is set in SSI, and if it not, you can redirect to a pure PHP page that sets the session cookie and sends back to the original shtml using a HTTP Redirect.

Community
  • 1
  • 1
LSerni
  • 55,617
  • 10
  • 65
  • 107
  • @Iserni Thanks for your answer. There still is something I'm not getting (my fault, of course). I just tried to create a simple PHP script and tell it – Ambrosia Oct 09 '15 at 10:10
  • @Iserni Thanks for your answer. I have a little update (clarification). If I create a session in a PHP script, then I continue to a .shtml page which includes an external PHP script via SSI, this included script does see the session and all variables stored in it. Doesn't work the other way around (e.g. if I include a PHP in .shtml page and this PHP creates a session, the following PHP scripts will not see the session. Still, the session is present in my browser so I guess it just doesn't get propagated as I expect. I tried to set use_cookies and use_trans_id but no change. – Ambrosia Oct 09 '15 at 10:53
  • I have tried to explain better what's happening. I have also thought of a workaround :-) – LSerni Oct 09 '15 at 14:14