diff options
author | ArthurHoaro <arthur@hoa.ro> | 2015-07-25 13:15:47 +0200 |
---|---|---|
committer | ArthurHoaro <arthur@hoa.ro> | 2015-08-22 10:10:55 +0200 |
commit | 06b6660a7e8891c6e1c47815cf50ee5b2ef5f270 (patch) | |
tree | b496ead047ccedb898c1917ee98d95c9cbde179c | |
parent | d7efade5d651ec60a05a86baa53f99188ad5d72c (diff) | |
download | Shaarli-06b6660a7e8891c6e1c47815cf50ee5b2ef5f270.tar.gz Shaarli-06b6660a7e8891c6e1c47815cf50ee5b2ef5f270.tar.zst Shaarli-06b6660a7e8891c6e1c47815cf50ee5b2ef5f270.zip |
Avoid Full Path Disclosure error on session error.
* Add a function to validate session ID.
* Generate a new session ID if an invalid token is passed.
-rw-r--r-- | application/Utils.php | 26 | ||||
-rwxr-xr-x | index.php | 41 | ||||
-rw-r--r-- | tests/UtilsTest.php | 19 |
3 files changed, 71 insertions, 15 deletions
diff --git a/application/Utils.php b/application/Utils.php index cd4724fa..fa18f158 100644 --- a/application/Utils.php +++ b/application/Utils.php | |||
@@ -137,4 +137,28 @@ function checkPHPVersion($minVersion, $curVersion) | |||
137 | ); | 137 | ); |
138 | } | 138 | } |
139 | } | 139 | } |
140 | ?> | 140 | |
141 | /** | ||
142 | * Validate session ID to prevent Full Path Disclosure. | ||
143 | * See #298. | ||
144 | * | ||
145 | * @param string $sessionId Session ID | ||
146 | * | ||
147 | * @return true if valid, false otherwise. | ||
148 | */ | ||
149 | function is_session_id_valid($sessionId) | ||
150 | { | ||
151 | if (empty($sessionId)) { | ||
152 | return false; | ||
153 | } | ||
154 | |||
155 | if (!$sessionId) { | ||
156 | return false; | ||
157 | } | ||
158 | |||
159 | if (!preg_match('/^[a-z0-9]{2,32}$/', $sessionId)) { | ||
160 | return false; | ||
161 | } | ||
162 | |||
163 | return true; | ||
164 | } | ||
@@ -43,19 +43,6 @@ define('shaarli_version','0.5.1'); | |||
43 | // http://server.com/x/shaarli --> /shaarli/ | 43 | // http://server.com/x/shaarli --> /shaarli/ |
44 | define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0))); | 44 | define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0))); |
45 | 45 | ||
46 | // Force cookie path (but do not change lifetime) | ||
47 | $cookie=session_get_cookie_params(); | ||
48 | $cookiedir = ''; if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/'; | ||
49 | session_set_cookie_params($cookie['lifetime'],$cookiedir,$_SERVER['SERVER_NAME']); // Set default cookie expiration and path. | ||
50 | |||
51 | // Set session parameters on server side. | ||
52 | define('INACTIVITY_TIMEOUT',3600); // (in seconds). If the user does not access any page within this time, his/her session is considered expired. | ||
53 | ini_set('session.use_cookies', 1); // Use cookies to store session. | ||
54 | ini_set('session.use_only_cookies', 1); // Force cookies for session (phpsessionID forbidden in URL). | ||
55 | ini_set('session.use_trans_sid', false); // Prevent PHP form using sessionID in URL if cookies are disabled. | ||
56 | session_name('shaarli'); | ||
57 | if (session_id() == '') session_start(); // Start session if needed (Some server auto-start sessions). | ||
58 | |||
59 | // PHP Settings | 46 | // PHP Settings |
60 | ini_set('max_input_time','60'); // High execution time in case of problematic imports/exports. | 47 | ini_set('max_input_time','60'); // High execution time in case of problematic imports/exports. |
61 | ini_set('memory_limit', '128M'); // Try to set max upload file size and read (May not work on some hosts). | 48 | ini_set('memory_limit', '128M'); // Try to set max upload file size and read (May not work on some hosts). |
@@ -87,6 +74,34 @@ try { | |||
87 | exit; | 74 | exit; |
88 | } | 75 | } |
89 | 76 | ||
77 | // Force cookie path (but do not change lifetime) | ||
78 | $cookie = session_get_cookie_params(); | ||
79 | $cookiedir = ''; | ||
80 | if (dirname($_SERVER['SCRIPT_NAME']) != '/') { | ||
81 | $cookiedir = dirname($_SERVER["SCRIPT_NAME"]).'/'; | ||
82 | } | ||
83 | // Set default cookie expiration and path. | ||
84 | session_set_cookie_params($cookie['lifetime'], $cookiedir, $_SERVER['SERVER_NAME']); | ||
85 | // Set session parameters on server side. | ||
86 | // If the user does not access any page within this time, his/her session is considered expired. | ||
87 | define('INACTIVITY_TIMEOUT', 3600); // in seconds. | ||
88 | // Use cookies to store session. | ||
89 | ini_set('session.use_cookies', 1); | ||
90 | // Force cookies for session (phpsessionID forbidden in URL). | ||
91 | ini_set('session.use_only_cookies', 1); | ||
92 | // Prevent PHP form using sessionID in URL if cookies are disabled. | ||
93 | ini_set('session.use_trans_sid', false); | ||
94 | |||
95 | // Regenerate session id if invalid or not defined in cookie. | ||
96 | if (isset($_COOKIE['shaarli']) && !is_session_id_valid($_COOKIE['shaarli'])) { | ||
97 | $_COOKIE['shaarli'] = uniqid(); | ||
98 | } | ||
99 | session_name('shaarli'); | ||
100 | // Start session if needed (Some server auto-start sessions). | ||
101 | if (session_id() == '') { | ||
102 | session_start(); | ||
103 | } | ||
104 | |||
90 | include "inc/rain.tpl.class.php"; //include Rain TPL | 105 | include "inc/rain.tpl.class.php"; //include Rain TPL |
91 | raintpl::$tpl_dir = $GLOBALS['config']['RAINTPL_TPL']; // template directory | 106 | raintpl::$tpl_dir = $GLOBALS['config']['RAINTPL_TPL']; // template directory |
92 | raintpl::$cache_dir = $GLOBALS['config']['RAINTPL_TMP']; // cache directory | 107 | raintpl::$cache_dir = $GLOBALS['config']['RAINTPL_TMP']; // cache directory |
diff --git a/tests/UtilsTest.php b/tests/UtilsTest.php index 28e15f5a..e39ce6be 100644 --- a/tests/UtilsTest.php +++ b/tests/UtilsTest.php | |||
@@ -150,5 +150,22 @@ class UtilsTest extends PHPUnit_Framework_TestCase | |||
150 | { | 150 | { |
151 | checkPHPVersion('5.3', '5.2'); | 151 | checkPHPVersion('5.3', '5.2'); |
152 | } | 152 | } |
153 | |||
154 | /** | ||
155 | * Test is_session_id_valid with a valid ID. | ||
156 | */ | ||
157 | public function testIsSessionIdValid() | ||
158 | { | ||
159 | $this->assertTrue(is_session_id_valid('123456789012345678901234567890az')); | ||
160 | } | ||
161 | |||
162 | /** | ||
163 | * Test is_session_id_valid with invalid IDs. | ||
164 | */ | ||
165 | public function testIsSessionIdInvalid() | ||
166 | { | ||
167 | $this->assertFalse(is_session_id_valid('')); | ||
168 | $this->assertFalse(is_session_id_valid(array())); | ||
169 | $this->assertFalse(is_session_id_valid('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=')); | ||
170 | } | ||
153 | } | 171 | } |
154 | ?> | ||