Session Cookies With External Reference Checking Not Working; Patch Attached
| From: | Andreas Pour | Date: | Mon, 28 Feb 2000 14:14:31 +0000 |
| Subject: | Session Cookies With External Reference Checking Not Working; Patch Attached | ||
| Groups: | php.version4 | ||
| Request: | Send a blank email to php-version4+get-11124@lists.php.net to get a copy of this message | ||
Hi,
Using cookies with external reference checking is broken. Actually,
Patch level 1 of PHP4 has all session-cookie checking broken if you set
session.referer_check to 0 in php.ini, this patch fixes the problem:
--- ext/session/session.c.orig Mon Feb 28 09:46:54 2000
+++ ext/session/session.c Mon Feb 28 09:47:53 2000
@@ -735,6 +735,7 @@
if (PS(id) &&
PS(extern_referer_chk)[0] != '\0' &&
+ PS(extern_referer_chk)[0] != '0' &&
zend_hash_find(&EG(symbol_table),
"HTTP_REFERER",
sizeof("HTTP_REFERER"), (void **) &data)
== SUCCESS &&
(*data)->type == IS_STRING &&
I have traced the problem to the external reference checking. In
ext/session/session.c, line 736 performs the referer check:
if (PS(id) &&
PS(extern_referer_chk)[0] != '\0' &&
zend_hash_find(&EG(symbol_table),
"HTTP_REFERER",
sizeof("HTTP_REFERER"), (void **) &data)
== SUCCESS &&
(*data)->type == IS_STRING &&
(*data)->value.str.len != 0 &&
strstr((*data)->value.str.val,
PS(extern_referer_chk)) == NULL)
Here HTTP_REFERER is correctly returned as the refering host, which is
'http://www.myhost.com/index.php'.
The problem is that
ps_globals.extern_referer_chk = '\001'. As this value is set to the
value of session.referer_check in the php.ini file, this condition will
*never* be satisfied.
It's not clear to me why you are looking at HTTP_REFERER. The relevant
variable is REMOTE_ADDR. And IMHO what you need to do is store the
REMOTE_ADDR somewhere *each* time you create a new sid, and the next
time that an SID is presented by the client (and hence a new one is not
created), compare the stored REMOTE_ADDR with the current request's
REMOTE_ADDR. The HTTP_REFERER has nothing to do with this.
But, where does one store this info? Since PHP is by default stateless,
the only sensible place is to use the session handling. Thus, when
storing a session after creating a new SID, PHP should self-register the
value of the REMOTE_ADDR, perhaps as the value
"PHP_SESSION_REMOTE_ADDR". In this case, checking for external
reference validity cannot occur until after the session-read function
has been executed (which will determine the value of the REMOTE_ADDR
which was sent along with the SID when it was created); and in fact
should be done immediately after the session-read and deserialization.
At that point no data should have yet been sent (as the read occurs as
part of the session start).
In short, if the client sends an SID, start the session, read the
session data, compare the client's REMOTE_ADDR to
PHP_SESSION_REMOTE_ADDR, and create/send a new SID if there is no match.
Hope you find this useful,
Andreas