php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #68970 output_add_rewrite_var() add session ID path begins with "//"
Submitted: 2015-02-02 02:42 UTC Modified: 2017-06-20 06:13 UTC
From: yohgaki@php.net Assigned: yohgaki (profile)
Status: Closed Package: Output Control
PHP Version: any OS: any
Private report: No CVE-ID: None
 [2015-02-02 02:42 UTC] yohgaki@php.net
Description:
------------
It seems url_scanner_ex.re has some problems.
It fails to handle some urls.

I'm trying to check if session.use_trans_sid=1 works or not.

Test script:
---------------
--TEST--
Test basic function : variation3 use_trans_sid
--INI--
session.use_strict_mode=0
session.use_only_cookies=0
session.use_trans_sid=1
session.save_handler=files
session.hash_bits_per_character=4
session.hash_function=0
session.gc_probability=1
session.gc_divisor=1000
session.gc_maxlifetime=300
session.save_path=
session.name=PHPSESSID
--SKIPIF--
<?php include('skipif.inc'); ?>
--FILE--
<?php

ob_start();

/*
 * Prototype : session.use_trans_sid=1
 * Description : Test basic functionality.
 * Source code : ext/session/session.c
 */

echo "*** Testing basic session functionality : variation3 use_trans_sid ***\n";


echo "*** test output_add_rewrite_var() ***\n";
output_add_rewrite_var('var', 'value');
echo '
<a href="/">test</a>
<a href="/#bar">test</a>
<a href="/?foo">test</a>
<a href="/?foo#bar">test</a>
<a href="/?foo=var">test</a>
<a href="/?foo=var#bar">test</a>
<a href="file.php">test</a>
<a href="file.php?foo">test</a>
<a href="file.php?foo=var">test</a>
<a href="http://php.net">test</a>
<a href="http://php.net/">test</a>
<a href="http://php.net/#bar">test</a>
<a href="http://php.net/?foo">test</a>
<a href="http://php.net/?foo#bar">test</a>
<a href="http://php.net/?foo=var">test</a>
<a href="http://php.net/?foo=var#bar">test</a>
<a href="http://php.net/file.php">test</a>
<a href="http://php.net/file.php#bar">test</a>
<a href="http://php.net/file.php?foo">test</a>
<a href="http://php.net/file.php?foo#bar">test</a>
<a href="http://php.net/file.php?foo=var">test</a>
<a href="http://php.net/file.php?foo=var#bar">test</a>
<a href="http://php.net/some/path/file.php">test</a>
<a href="http://php.net/some/path/file.php?foo">test</a>
<a href="http://php.net/some/path/file.php?foo=var">test</a>
<a href="http://php.net/some/path/file.php?foo=var#bar">test</a>
<a href="https://php.net">test</a>
<a href="https://php.net/">test</a>
<a href="https://php.net/?foo=var#bar">test</a>
<a href="https://php.net/file.php">test</a>
<a href="https://php.net/file.php?foo=var#bar">test</a>
<a href="https://php.net/some/path/file.php">test</a>
<a href="https://php.net/some/path/file.php?foo=var#bar">test</a>
<a href="//php.net">test</a>
<a href="//php.net/">test</a>
<a href="//php.net/#bar">test</a>
<a href="//php.net/?foo">test</a>
<a href="//php.net/?foo#bar">test</a>
<a href="//php.net/?foo=var">test</a>
<a href="//php.net/?foo=var#bar">test</a>
<a href="//php.net/file.php">test</a>
<a href="//php.net/file.php#bar">test</a>
<a href="//php.net/file.php?foo">test</a>
<a href="//php.net/file.php?foo#bar">test</a>
<a href="//php.net/file.php?foo=var">test</a>
<a href="//php.net/file.php?foo=var#bar">test</a>
<a href="//php.net/some/path/file.php">test</a>
<a href="//php.net/some/path/file.php?foo">test</a>
<a href="//php.net/some/path/file.php?foo=var">test</a>
<a href="//php.net/some/path/file.php?foo=var#bar">test</a>
<form action="script.php" method="post">
  <input type="text" name="test1"></input>
  <input type="text" name="test2" />
</form>
';
output_reset_rewrite_vars();


echo "*** Test trans sid ***\n";
ob_start();
$session_id = 'testid';
session_id($session_id);
echo '
<a href="file.php">test</a>
<a href="http://php.net">test</a>
<a href="http://php.net/">test</a>
<a href="http://php.net/file.php">test</a>
<form action="script.php" method="post">
  <input type="text" name="testa" />
  <input type="text" name="testb" />
</form>
';
echo "*** Cleanup ***\n";
var_dump(session_id($session_id));
var_dump(session_start());
var_dump(session_destroy());

ob_end_flush();
?>
--EXPECTF--


Actual result:
--------------
I get following output from output_add_rewrite_var().

<a href="/?PHPSESSID=testid">test</a>
<a href="/?PHPSESSID=testid#bar">test</a>
<a href="/?foo&PHPSESSID=testid">test</a>
<a href="/?foo&PHPSESSID=testid#bar">test</a>
<a href="/?foo=var&PHPSESSID=testid">test</a>
<a href="/?foo=var&PHPSESSID=testid#bar">test</a>
<a href="file.php?PHPSESSID=testid">test</a>
<a href="file.php?foo&PHPSESSID=testid">test</a>
<a href="file.php?foo=var&PHPSESSID=testid">test</a>
<a href="http://php.net">test</a>
<a href="http://php.net/">test</a>
<a href="http://php.net/#bar">test</a>
<a href="http://php.net/?foo">test</a>
<a href="http://php.net/?foo#bar">test</a>
<a href="http://php.net/?foo=var">test</a>
<a href="http://php.net/?foo=var#bar">test</a>
<a href="http://php.net/file.php">test</a>
<a href="http://php.net/file.php#bar">test</a>
<a href="http://php.net/file.php?foo">test</a>
<a href="http://php.net/file.php?foo#bar">test</a>
<a href="http://php.net/file.php?foo=var">test</a>
<a href="http://php.net/file.php?foo=var#bar">test</a>
<a href="http://php.net/some/path/file.php">test</a>
<a href="http://php.net/some/path/file.php?foo">test</a>
<a href="http://php.net/some/path/file.php?foo=var">test</a>
<a href="http://php.net/some/path/file.php?foo=var#bar">test</a>
<a href="https://php.net">test</a>
<a href="https://php.net/">test</a>
<a href="https://php.net/?foo=var#bar">test</a>
<a href="https://php.net/file.php">test</a>
<a href="https://php.net/file.php?foo=var#bar">test</a>
<a href="https://php.net/some/path/file.php">test</a>
<a href="https://php.net/some/path/file.php?foo=var#bar">test</a>
<a href="//php.net?PHPSESSID=testid">test</a>
<a href="//php.net/?PHPSESSID=testid">test</a>
<a href="//php.net/?PHPSESSID=testid#bar">test</a>
<a href="//php.net/?foo&PHPSESSID=testid">test</a>
<a href="//php.net/?foo&PHPSESSID=testid#bar">test</a>
<a href="//php.net/?foo=var&PHPSESSID=testid">test</a>
<a href="//php.net/?foo=var&PHPSESSID=testid#bar">test</a>
<a href="//php.net/file.php?PHPSESSID=testid">test</a>
<a href="//php.net/file.php?PHPSESSID=testid#bar">test</a>
<a href="//php.net/file.php?foo&PHPSESSID=testid">test</a>
<a href="//php.net/file.php?foo&PHPSESSID=testid#bar">test</a>
<a href="//php.net/file.php?foo=var&PHPSESSID=testid">test</a>
<a href="//php.net/file.php?foo=var&PHPSESSID=testid#bar">test</a>
<a href="//php.net/some/path/file.php?PHPSESSID=testid">test</a>
<a href="//php.net/some/path/file.php?foo&PHPSESSID=testid">test</a>
<a href="//php.net/some/path/file.php?foo=var&PHPSESSID=testid">test</a>
<a href="//php.net/some/path/file.php?foo=var&PHPSESSID=testid#bar">test</a>
<form action="script.php" method="post"><input type="hidden" name="PHPSESSID" value="testid" />
  <input type="text" name="test1"></input>
  <input type="text" name="test2" />
</form>

Patches

bug68063.patch (last revision 2016-01-13 02:09 UTC by yohgaki@php.net)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-02-02 02:46 UTC] yohgaki@php.net
-Assigned To: +Assigned To: mike
 [2015-02-02 02:46 UTC] yohgaki@php.net
Mike, could you take care url_scanner_ex.re issue?
I think output control does this since your new output API. (I really like your new output API, BTW)

There may be issues in session module also. I'll take care session module issue.
 [2015-02-02 06:28 UTC] yohgaki@php.net
-Summary: output_add_rewrite_var() fails to add some URLs +Summary: output_add_rewrite_var() add session ID path begins with "//"
 [2015-02-02 06:28 UTC] yohgaki@php.net
My initial bug report was bogus. 
I changed the bug title. output_add_rewrite_var() should not add session ID for anything look like full path including "//". i.e. If output_add_rewrite_var() adds session ID to other sites, it means session module is leaking session ID to other sites. Trans SID must work only for originating site.
 [2015-02-02 08:37 UTC] mike@php.net
Ugh, I've no idea about re2c. I surely didn't touch this more then necessary, I even didn't convert the output handler from a compat-style to a new-style one, i.e. moving global state to a handler context :-/
 [2015-02-02 09:05 UTC] yohgaki@php.net
I've committed the test script to master.

https://github.com/php/php-src/blob/master/ext/session/tests/session_basic3.phpt

This bug is security related when trans sid is enabled.
 [2015-02-02 09:06 UTC] yohgaki@php.net
-Assigned To: mike +Assigned To: yohgaki
 [2015-02-02 09:06 UTC] yohgaki@php.net
Assigned to me. Feel free to fix it anyone! I don't have much time for this...
 [2015-05-24 06:31 UTC] yohgaki@php.net
-Type: Bug +Type: Security -Private report: No +Private report: Yes
 [2015-05-24 06:31 UTC] yohgaki@php.net
I understand this bug causes serious security issue when user enable transid. I was not able to spend time for this for a long time. 

Changed bug type.
 [2015-09-08 10:01 UTC] yohgaki@php.net
-PHP Version: master-Git-2015-02-02 (Git) +PHP Version: any
 [2015-09-08 10:01 UTC] yohgaki@php.net
Related issue should be fixed.

http://lxr.php.net/xref/PHP_TRUNK/ext/session/session.c#1501

Session module has to call php_url_scanner_reset_vars(). However, php_url_scanner_reset_vars() removes all rewrite vars including set by other than session module. Therefore, above line is commented out.

URL rewrite parser (ext/standard/url_scanner_ex.re) and API must be improved to fix this bug completely.
 [2016-01-13 02:09 UTC] yohgaki@php.net
The following patch has been added/updated:

Patch Name: bug68063.patch
Revision:   1452650956
URL:        https://bugs.php.net/patch-display.php?bug=68970&patch=bug68063.patch&revision=1452650956
 [2016-10-17 06:41 UTC] yohgaki@php.net
-Status: Assigned +Status: Closed
 [2016-10-17 06:41 UTC] yohgaki@php.net
Fixed in PHP 5.6/7.0/7.1/master
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 12:01:28 2024 UTC