This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * Elgg session management |
||
5 | * Functions to manage logins |
||
6 | * |
||
7 | * @package Elgg.Core |
||
8 | * @subpackage Session |
||
9 | */ |
||
10 | |||
11 | /** |
||
12 | * Elgg magic session |
||
13 | * @deprecated 1.9 |
||
14 | */ |
||
15 | global $SESSION; |
||
16 | |||
17 | /** |
||
18 | * Gets Elgg's session object |
||
19 | * |
||
20 | * @return \ElggSession |
||
21 | * @since 1.9 |
||
22 | */ |
||
23 | function elgg_get_session() { |
||
24 | return _elgg_services()->session; |
||
25 | } |
||
26 | |||
27 | /** |
||
28 | * Return the current logged in user, or null if no user is logged in. |
||
29 | * |
||
30 | * @return \ElggUser |
||
31 | */ |
||
32 | function elgg_get_logged_in_user_entity() { |
||
33 | return _elgg_services()->session->getLoggedInUser(); |
||
34 | } |
||
35 | |||
36 | /** |
||
37 | * Return the current logged in user by guid. |
||
38 | * |
||
39 | * @see elgg_get_logged_in_user_entity() |
||
40 | * @return int |
||
41 | */ |
||
42 | function elgg_get_logged_in_user_guid() { |
||
43 | 1 | return _elgg_services()->session->getLoggedInUserGuid(); |
|
44 | } |
||
45 | |||
46 | /** |
||
47 | * Returns whether or not the user is currently logged in |
||
48 | * |
||
49 | * @return bool |
||
50 | */ |
||
51 | function elgg_is_logged_in() { |
||
52 | return _elgg_services()->session->isLoggedIn(); |
||
53 | } |
||
54 | |||
55 | /** |
||
56 | * Returns whether or not the viewer is currently logged in and an admin user. |
||
57 | * |
||
58 | * @return bool |
||
59 | */ |
||
60 | function elgg_is_admin_logged_in() { |
||
61 | return _elgg_services()->session->isAdminLoggedIn(); |
||
62 | } |
||
63 | |||
64 | /** |
||
65 | * Check if the given user has full access. |
||
66 | * |
||
67 | * @todo: Will always return full access if the user is an admin. |
||
68 | * |
||
69 | * @param int $user_guid The user to check |
||
70 | * |
||
71 | * @return bool |
||
72 | * @since 1.7.1 |
||
73 | */ |
||
74 | function elgg_is_admin_user($user_guid) { |
||
75 | global $CONFIG; |
||
76 | |||
77 | $user_guid = (int)$user_guid; |
||
78 | |||
79 | $current_user = elgg_get_logged_in_user_entity(); |
||
80 | if ($current_user && $current_user->guid == $user_guid) { |
||
81 | return $current_user->isAdmin(); |
||
82 | } |
||
83 | |||
84 | // cannot use magic metadata here because of recursion |
||
85 | |||
86 | // must support the old way of getting admin from metadata |
||
87 | // in order to run the upgrade to move it into the users table. |
||
88 | $version = (int) datalist_get('version'); |
||
89 | |||
90 | if ($version < 2010040201) { |
||
91 | $admin = elgg_get_metastring_id('admin'); |
||
92 | $yes = elgg_get_metastring_id('yes'); |
||
93 | $one = elgg_get_metastring_id('1'); |
||
94 | |||
95 | $query = "SELECT 1 FROM {$CONFIG->dbprefix}users_entity as e, |
||
96 | {$CONFIG->dbprefix}metadata as md |
||
97 | WHERE ( |
||
98 | md.name_id = '$admin' |
||
99 | AND md.value_id IN ('$yes', '$one') |
||
100 | AND e.guid = md.entity_guid |
||
101 | AND e.guid = {$user_guid} |
||
102 | AND e.banned = 'no' |
||
103 | )"; |
||
104 | } else { |
||
105 | $query = "SELECT 1 FROM {$CONFIG->dbprefix}users_entity as e |
||
106 | WHERE ( |
||
107 | e.guid = {$user_guid} |
||
108 | AND e.admin = 'yes' |
||
109 | )"; |
||
110 | } |
||
111 | |||
112 | // normalizing the results from get_data() |
||
113 | // See #1242 |
||
114 | $info = get_data($query); |
||
115 | if (!((is_array($info) && count($info) < 1) || $info === false)) { |
||
116 | return true; |
||
117 | } |
||
118 | return false; |
||
119 | } |
||
120 | |||
121 | /** |
||
122 | * Perform user authentication with a given username and password. |
||
123 | * |
||
124 | * @warning This returns an error message on failure. Use the identical operator to check |
||
125 | * for access: if (true === elgg_authenticate()) { ... }. |
||
126 | * |
||
127 | * |
||
128 | * @see login |
||
129 | * |
||
130 | * @param string $username The username |
||
131 | * @param string $password The password |
||
132 | * |
||
133 | * @return true|string True or an error message on failure |
||
134 | * @access private |
||
135 | */ |
||
136 | function elgg_authenticate($username, $password) { |
||
137 | $pam = new \ElggPAM('user'); |
||
138 | $credentials = array('username' => $username, 'password' => $password); |
||
139 | $result = $pam->authenticate($credentials); |
||
140 | if (!$result) { |
||
141 | return $pam->getFailureMessage(); |
||
142 | } |
||
143 | return true; |
||
144 | } |
||
145 | |||
146 | /** |
||
147 | * Hook into the PAM system which accepts a username and password and attempts to authenticate |
||
148 | * it against a known user. |
||
149 | * |
||
150 | * @param array $credentials Associated array of credentials passed to |
||
151 | * Elgg's PAM system. This function expects |
||
152 | * 'username' and 'password' (cleartext). |
||
153 | * |
||
154 | * @return bool |
||
155 | * @throws LoginException |
||
156 | * @access private |
||
157 | */ |
||
158 | function pam_auth_userpass(array $credentials = array()) { |
||
159 | |||
160 | if (!isset($credentials['username']) || !isset($credentials['password'])) { |
||
161 | return false; |
||
162 | } |
||
163 | |||
164 | $user = get_user_by_username($credentials['username']); |
||
165 | if (!$user) { |
||
166 | throw new \LoginException(_elgg_services()->translator->translate('LoginException:UsernameFailure')); |
||
167 | } |
||
168 | |||
169 | if (check_rate_limit_exceeded($user->guid)) { |
||
170 | throw new \LoginException(_elgg_services()->translator->translate('LoginException:AccountLocked')); |
||
171 | } |
||
172 | |||
173 | $password_svc = _elgg_services()->passwords; |
||
174 | $password = $credentials['password']; |
||
175 | $hash = $user->password_hash; |
||
176 | |||
177 | if (!$hash) { |
||
178 | // try legacy hash |
||
179 | $legacy_hash = $password_svc->generateLegacyHash($user, $password); |
||
180 | View Code Duplication | if ($user->password !== $legacy_hash) { |
|
181 | log_login_failure($user->guid); |
||
182 | throw new \LoginException(_elgg_services()->translator->translate('LoginException:PasswordFailure')); |
||
183 | } |
||
184 | |||
185 | // migrate password |
||
186 | $password_svc->forcePasswordReset($user, $password); |
||
187 | return true; |
||
188 | } |
||
189 | |||
190 | View Code Duplication | if (!$password_svc->verify($password, $hash)) { |
|
191 | log_login_failure($user->guid); |
||
192 | throw new \LoginException(_elgg_services()->translator->translate('LoginException:PasswordFailure')); |
||
193 | } |
||
194 | |||
195 | if ($password_svc->needsRehash($hash)) { |
||
196 | $password_svc->forcePasswordReset($user, $password); |
||
197 | } |
||
198 | |||
199 | return true; |
||
200 | } |
||
201 | |||
202 | /** |
||
203 | * Log a failed login for $user_guid |
||
204 | * |
||
205 | * @param int $user_guid User GUID |
||
206 | * |
||
207 | * @return bool |
||
208 | */ |
||
209 | function log_login_failure($user_guid) { |
||
210 | $user_guid = (int)$user_guid; |
||
211 | $user = get_entity($user_guid); |
||
212 | |||
213 | if (($user_guid) && ($user) && ($user instanceof \ElggUser)) { |
||
214 | $fails = (int)$user->getPrivateSetting("login_failures"); |
||
215 | $fails++; |
||
216 | |||
217 | $user->setPrivateSetting("login_failures", $fails); |
||
218 | $user->setPrivateSetting("login_failure_$fails", time()); |
||
219 | return true; |
||
220 | } |
||
221 | |||
222 | return false; |
||
223 | } |
||
224 | |||
225 | /** |
||
226 | * Resets the fail login count for $user_guid |
||
227 | * |
||
228 | * @param int $user_guid User GUID |
||
229 | * |
||
230 | * @return bool true on success (success = user has no logged failed attempts) |
||
231 | */ |
||
232 | function reset_login_failure_count($user_guid) { |
||
233 | $user_guid = (int)$user_guid; |
||
234 | $user = get_entity($user_guid); |
||
235 | |||
236 | if (($user_guid) && ($user) && ($user instanceof \ElggUser)) { |
||
237 | $fails = (int)$user->getPrivateSetting("login_failures"); |
||
238 | |||
239 | if ($fails) { |
||
240 | for ($n = 1; $n <= $fails; $n++) { |
||
241 | $user->removePrivateSetting("login_failure_$n"); |
||
242 | } |
||
243 | |||
244 | $user->removePrivateSetting("login_failures"); |
||
245 | |||
246 | return true; |
||
247 | } |
||
248 | |||
249 | // nothing to reset |
||
250 | return true; |
||
251 | } |
||
252 | |||
253 | return false; |
||
254 | } |
||
255 | |||
256 | /** |
||
257 | * Checks if the rate limit of failed logins has been exceeded for $user_guid. |
||
258 | * |
||
259 | * @param int $user_guid User GUID |
||
260 | * |
||
261 | * @return bool on exceeded limit. |
||
262 | */ |
||
263 | function check_rate_limit_exceeded($user_guid) { |
||
264 | // 5 failures in 5 minutes causes temporary block on logins |
||
265 | $limit = 5; |
||
266 | $user_guid = (int)$user_guid; |
||
267 | $user = get_entity($user_guid); |
||
268 | |||
269 | if (($user_guid) && ($user) && ($user instanceof \ElggUser)) { |
||
270 | $fails = (int)$user->getPrivateSetting("login_failures"); |
||
271 | if ($fails >= $limit) { |
||
272 | $cnt = 0; |
||
273 | $time = time(); |
||
274 | for ($n = $fails; $n > 0; $n--) { |
||
275 | $f = $user->getPrivateSetting("login_failure_$n"); |
||
276 | if ($f > $time - (60 * 5)) { |
||
277 | $cnt++; |
||
278 | } |
||
279 | |||
280 | if ($cnt == $limit) { |
||
281 | // Limit reached |
||
282 | return true; |
||
283 | } |
||
284 | } |
||
285 | } |
||
286 | } |
||
287 | |||
288 | return false; |
||
289 | } |
||
290 | |||
291 | /** |
||
292 | * Set a cookie, but allow plugins to customize it first. |
||
293 | * |
||
294 | * To customize all cookies, register for the 'init:cookie', 'all' event. |
||
295 | * |
||
296 | * @param \ElggCookie $cookie The cookie that is being set |
||
297 | * @return bool |
||
298 | * @since 1.9 |
||
299 | */ |
||
300 | function elgg_set_cookie(\ElggCookie $cookie) { |
||
301 | if (elgg_trigger_event('init:cookie', $cookie->name, $cookie)) { |
||
0 ignored issues
–
show
|
|||
302 | return setcookie($cookie->name, $cookie->value, $cookie->expire, $cookie->path, |
||
303 | $cookie->domain, $cookie->secure, $cookie->httpOnly); |
||
304 | } |
||
305 | return false; |
||
306 | } |
||
307 | |||
308 | /** |
||
309 | * Logs in a specified \ElggUser. For standard registration, use in conjunction |
||
310 | * with elgg_authenticate. |
||
311 | * |
||
312 | * @see elgg_authenticate |
||
313 | * |
||
314 | * @param \ElggUser $user A valid Elgg user object |
||
315 | * @param boolean $persistent Should this be a persistent login? |
||
316 | * |
||
317 | * @return true or throws exception |
||
318 | * @throws LoginException |
||
319 | */ |
||
320 | function login(\ElggUser $user, $persistent = false) { |
||
321 | if ($user->isBanned()) { |
||
322 | throw new \LoginException(elgg_echo('LoginException:BannedUser')); |
||
323 | } |
||
324 | |||
325 | $session = _elgg_services()->session; |
||
326 | |||
327 | // give plugins a chance to reject the login of this user (no user in session!) |
||
328 | if (!elgg_trigger_before_event('login', 'user', $user)) { |
||
0 ignored issues
–
show
$user is of type object<ElggUser> , but the function expects a string|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
329 | throw new \LoginException(elgg_echo('LoginException:Unknown')); |
||
330 | } |
||
331 | |||
332 | // #5933: set logged in user early so code in login event will be able to |
||
333 | // use elgg_get_logged_in_user_entity(). |
||
334 | $session->setLoggedInUser($user); |
||
335 | |||
336 | // deprecate event |
||
337 | $message = "The 'login' event was deprecated. Register for 'login:before' or 'login:after'"; |
||
338 | $version = "1.9"; |
||
339 | if (!elgg_trigger_deprecated_event('login', 'user', $user, $message, $version)) { |
||
0 ignored issues
–
show
$user is of type object<ElggUser> , but the function expects a string|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
340 | $session->removeLoggedInUser(); |
||
341 | throw new \LoginException(elgg_echo('LoginException:Unknown')); |
||
342 | } |
||
343 | |||
344 | // if remember me checked, set cookie with token and store hash(token) for user |
||
345 | if ($persistent) { |
||
346 | _elgg_services()->persistentLogin->makeLoginPersistent($user); |
||
347 | } |
||
348 | |||
349 | // User's privilege has been elevated, so change the session id (prevents session fixation) |
||
350 | $session->migrate(); |
||
351 | |||
352 | set_last_login($user->guid); |
||
353 | reset_login_failure_count($user->guid); |
||
354 | |||
355 | elgg_trigger_after_event('login', 'user', $user); |
||
0 ignored issues
–
show
$user is of type object<ElggUser> , but the function expects a string|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
356 | |||
357 | // if memcache is enabled, invalidate the user in memcache @see https://github.com/Elgg/Elgg/issues/3143 |
||
358 | if (is_memcache_available()) { |
||
359 | $guid = $user->getGUID(); |
||
360 | // this needs to happen with a shutdown function because of the timing with set_last_login() |
||
361 | register_shutdown_function("_elgg_invalidate_memcache_for_entity", $guid); |
||
362 | } |
||
363 | |||
364 | return true; |
||
365 | } |
||
366 | |||
367 | /** |
||
368 | * Log the current user out |
||
369 | * |
||
370 | * @return bool |
||
371 | */ |
||
372 | function logout() { |
||
373 | $session = _elgg_services()->session; |
||
374 | $user = $session->getLoggedInUser(); |
||
375 | if (!$user) { |
||
376 | return false; |
||
377 | } |
||
378 | |||
379 | if (!elgg_trigger_before_event('logout', 'user', $user)) { |
||
0 ignored issues
–
show
$user is of type object<ElggUser> , but the function expects a string|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
380 | return false; |
||
381 | } |
||
382 | |||
383 | // deprecate event |
||
384 | $message = "The 'logout' event was deprecated. Register for 'logout:before' or 'logout:after'"; |
||
385 | $version = "1.9"; |
||
386 | if (!elgg_trigger_deprecated_event('logout', 'user', $user, $message, $version)) { |
||
0 ignored issues
–
show
$user is of type object<ElggUser> , but the function expects a string|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
387 | return false; |
||
388 | } |
||
389 | |||
390 | _elgg_services()->persistentLogin->removePersistentLogin(); |
||
391 | |||
392 | // pass along any messages into new session |
||
393 | $old_msg = $session->get('msg'); |
||
394 | $session->invalidate(); |
||
395 | $session->set('msg', $old_msg); |
||
396 | |||
397 | elgg_trigger_after_event('logout', 'user', $user); |
||
0 ignored issues
–
show
$user is of type object<ElggUser> , but the function expects a string|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
398 | |||
399 | return true; |
||
400 | } |
||
401 | |||
402 | /** |
||
403 | * Initializes the session and checks for the remember me cookie |
||
404 | * |
||
405 | * @return bool |
||
406 | * @access private |
||
407 | */ |
||
408 | function _elgg_session_boot() { |
||
409 | |||
410 | elgg_register_action('login', '', 'public'); |
||
411 | elgg_register_action('logout'); |
||
412 | register_pam_handler('pam_auth_userpass'); |
||
413 | |||
414 | $session = _elgg_services()->session; |
||
415 | $session->start(); |
||
416 | |||
417 | // test whether we have a user session |
||
418 | if ($session->has('guid')) { |
||
419 | $user = _elgg_services()->entityTable->get($session->get('guid'), 'user'); |
||
420 | if (!$user) { |
||
421 | // OMG user has been deleted. |
||
422 | $session->invalidate(); |
||
423 | forward(''); |
||
424 | } |
||
425 | |||
426 | $session->setLoggedInUser($user); |
||
0 ignored issues
–
show
$user of type object<ElggEntity> is not a sub-type of object<ElggUser> . It seems like you assume a child class of the class ElggEntity to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. ![]() |
|||
427 | |||
428 | _elgg_services()->persistentLogin->replaceLegacyToken($user); |
||
0 ignored issues
–
show
$user of type object<ElggEntity> is not a sub-type of object<ElggUser> . It seems like you assume a child class of the class ElggEntity to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. ![]() |
|||
429 | } else { |
||
430 | $user = _elgg_services()->persistentLogin->bootSession(); |
||
431 | if ($user) { |
||
432 | $session->setLoggedInUser($user); |
||
433 | } |
||
434 | } |
||
435 | |||
436 | if ($session->has('guid')) { |
||
437 | set_last_action($session->get('guid')); |
||
438 | } |
||
439 | |||
440 | // initialize the deprecated global session wrapper |
||
441 | global $SESSION; |
||
442 | $SESSION = new \Elgg\DeprecationWrapper($session, "\$SESSION is deprecated", 1.9); |
||
443 | |||
444 | // logout a user with open session who has been banned |
||
445 | $user = $session->getLoggedInUser(); |
||
446 | if ($user && $user->isBanned()) { |
||
447 | logout(); |
||
448 | return false; |
||
449 | } |
||
450 | |||
451 | return true; |
||
452 | } |
||
453 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: