Skip to content

Commit

Permalink
Avoid Full Path Disclosure error on session error.
Browse files Browse the repository at this point in the history
  * Add a function to validate session ID.
  * Generate a new session ID if an invalid token is passed.
  • Loading branch information
ArthurHoaro committed Aug 22, 2015
1 parent d7efade commit 06b6660
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 15 deletions.
26 changes: 25 additions & 1 deletion application/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,28 @@ function checkPHPVersion($minVersion, $curVersion)
);
}
}
?>

/**
* Validate session ID to prevent Full Path Disclosure.
* See #298.
*
* @param string $sessionId Session ID
*
* @return true if valid, false otherwise.
*/
function is_session_id_valid($sessionId)
{
if (empty($sessionId)) {
return false;
}

if (!$sessionId) {
return false;
}

if (!preg_match('/^[a-z0-9]{2,32}$/', $sessionId)) {
return false;
}

return true;
}
41 changes: 28 additions & 13 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,6 @@
// http://server.com/x/shaarli --> /shaarli/
define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0)));

// Force cookie path (but do not change lifetime)
$cookie=session_get_cookie_params();
$cookiedir = ''; if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/';
session_set_cookie_params($cookie['lifetime'],$cookiedir,$_SERVER['SERVER_NAME']); // Set default cookie expiration and path.

// Set session parameters on server side.
define('INACTIVITY_TIMEOUT',3600); // (in seconds). If the user does not access any page within this time, his/her session is considered expired.
ini_set('session.use_cookies', 1); // Use cookies to store session.
ini_set('session.use_only_cookies', 1); // Force cookies for session (phpsessionID forbidden in URL).
ini_set('session.use_trans_sid', false); // Prevent PHP form using sessionID in URL if cookies are disabled.
session_name('shaarli');
if (session_id() == '') session_start(); // Start session if needed (Some server auto-start sessions).

// PHP Settings
ini_set('max_input_time','60'); // High execution time in case of problematic imports/exports.
ini_set('memory_limit', '128M'); // Try to set max upload file size and read (May not work on some hosts).
Expand Down Expand Up @@ -87,6 +74,34 @@
exit;
}

// Force cookie path (but do not change lifetime)
$cookie = session_get_cookie_params();
$cookiedir = '';
if (dirname($_SERVER['SCRIPT_NAME']) != '/') {
$cookiedir = dirname($_SERVER["SCRIPT_NAME"]).'/';
}
// Set default cookie expiration and path.
session_set_cookie_params($cookie['lifetime'], $cookiedir, $_SERVER['SERVER_NAME']);
// Set session parameters on server side.
// If the user does not access any page within this time, his/her session is considered expired.
define('INACTIVITY_TIMEOUT', 3600); // in seconds.
// Use cookies to store session.
ini_set('session.use_cookies', 1);
// Force cookies for session (phpsessionID forbidden in URL).
ini_set('session.use_only_cookies', 1);
// Prevent PHP form using sessionID in URL if cookies are disabled.
ini_set('session.use_trans_sid', false);

// Regenerate session id if invalid or not defined in cookie.
if (isset($_COOKIE['shaarli']) && !is_session_id_valid($_COOKIE['shaarli'])) {
$_COOKIE['shaarli'] = uniqid();
}
session_name('shaarli');
// Start session if needed (Some server auto-start sessions).
if (session_id() == '') {
session_start();
}

include "inc/rain.tpl.class.php"; //include Rain TPL
raintpl::$tpl_dir = $GLOBALS['config']['RAINTPL_TPL']; // template directory
raintpl::$cache_dir = $GLOBALS['config']['RAINTPL_TMP']; // cache directory
Expand Down
19 changes: 18 additions & 1 deletion tests/UtilsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,5 +150,22 @@ public function testCheckSupportedPHPVersion52()
{
checkPHPVersion('5.3', '5.2');
}

/**
* Test is_session_id_valid with a valid ID.
*/
public function testIsSessionIdValid()
{
$this->assertTrue(is_session_id_valid('123456789012345678901234567890az'));
}

/**
* Test is_session_id_valid with invalid IDs.
*/
public function testIsSessionIdInvalid()
{
$this->assertFalse(is_session_id_valid(''));
$this->assertFalse(is_session_id_valid(array()));
$this->assertFalse(is_session_id_valid('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI='));
}
}
?>

0 comments on commit 06b6660

Please sign in to comment.