Issues (2473)

Branch: master

Security Analysis    no vulnerabilities found

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

engine/classes/ElggSession.php (5 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
use Symfony\Component\HttpFoundation\Session\SessionInterface;
4
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
5
use Symfony\Component\HttpFoundation\Session\Session;
6
7
/**
8
 * Elgg Session Management
9
 *
10
 * Reserved keys: last_forward_from, msg, sticky_forms, user, guid, id, code, name, username
11
 * Deprecated keys: user, id, name, username
12
 * 
13
 * \ArrayAccess was deprecated in Elgg 1.9. This means you should use 
14
 * $session->get('foo') rather than $session['foo'].
15
 * Warning: You can not access multidimensional arrays through \ArrayAccess like
16
 * this $session['foo']['bar']
17
 *
18
 * @package    Elgg.Core
19
 * @subpackage Session
20
 * @see        elgg_get_session()
21
 */
22
class ElggSession implements \ArrayAccess {
23
24
	/**
25
	 * @var SessionInterface
26
	 */
27
	protected $storage;
28
29
	/**
30
	 * @var \ElggUser|null
31
	 */
32
	protected $logged_in_user;
33
34
	/**
35
	 * @var bool
36
	 */
37
	protected $ignore_access = false;
38
39
	/**
40
	 * Constructor
41
	 *
42
	 * @param SessionInterface $storage The underlying Session implementation
43
	 * @access private Use elgg_get_session()
44
	 */
45 79
	public function __construct(SessionInterface $storage) {
46 79
		$this->storage = $storage;
47 79
	}
48
49
	/**
50
	 * Start the session
51
	 *
52
	 * @return boolean
53
	 * @throws RuntimeException If session fails to start.
54
	 * @since 1.9
55
	 */
56 3
	public function start() {
57 3
		$result = $this->storage->start();
58 3
		$this->generateSessionToken();
59 3
		return $result;
60
	}
61
62
	/**
63
	 * Migrates the session to a new session id while maintaining session attributes
64
	 *
65
	 * @param boolean $destroy Whether to delete the session or let gc handle clean up
66
	 * @return boolean
67
	 * @since 1.9
68
	 */
69 2
	public function migrate($destroy = false) {
70 2
		return $this->storage->migrate($destroy);
71
	}
72
73
	/**
74
	 * Invalidates the session
75
	 *
76
	 * Deletes session data and session persistence. Starts a new session.
77
	 *
78
	 * @return boolean
79
	 * @since 1.9
80
	 */
81 1
	public function invalidate() {
82 1
		$this->storage->clear();
83 1
		$this->logged_in_user = null;
84 1
		$result = $this->migrate(true);
85 1
		$this->generateSessionToken();
86 1
		return $result;
87
	}
88
89
	/**
90
	 * Has the session been started
91
	 *
92
	 * @return boolean
93
	 * @since 1.9
94
	 */
95
	public function isStarted() {
96
		return $this->storage->isStarted();
97
	}
98
99
	/**
100
	 * Get the session ID
101
	 *
102
	 * @return string
103
	 * @since 1.9
104
	 */
105 2
	public function getId() {
106 2
		return $this->storage->getId();
107
	}
108
109
	/**
110
	 * Set the session ID
111
	 *
112
	 * @param string $id Session ID
113
	 * @return void
114
	 * @since 1.9
115
	 */
116
	public function setId($id) {
117
		$this->storage->setId($id);
118
	}
119
120
	/**
121
	 * Get the session name
122
	 *
123
	 * @return string
124
	 * @since 1.9
125
	 */
126
	public function getName() {
127
		return $this->storage->getName();
128
	}
129
130
	/**
131
	 * Set the session name
132
	 *
133
	 * @param string $name Session name
134
	 * @return void
135
	 * @since 1.9
136
	 */
137
	public function setName($name) {
138
		$this->storage->setName($name);
139
	}
140
141
	/**
142
	 * Get an attribute of the session
143
	 *
144
	 * @param string $name    Name of the attribute to get
145
	 * @param mixed  $default Value to return if attribute is not set (default is null)
146
	 * @return mixed
147
	 */
148 13
	public function get($name, $default = null) {
149 13
		return $this->storage->get($name, $default);
150
	}
151
152
	/**
153
	 * Set an attribute
154
	 *
155
	 * @param string $name  Name of the attribute to set
156
	 * @param mixed  $value Value to be set
157
	 * @return void
158
	 */
159 11
	public function set($name, $value) {
160 11
		$this->storage->set($name, $value);
161 11
	}
162
163
	/**
164
	 * Remove an attribute
165
	 *
166
	 * @param string $name The name of the attribute to remove
167
	 * @return mixed The removed attribute
168
	 * @since 1.9
169
	 */
170 2
	public function remove($name) {
171 2
		return $this->storage->remove($name);
172
	}
173
174
	/**
175
	 * Alias to offsetUnset()
176
	 *
177
	 * @param string $key Name
178
	 * @return void
179
	 * @deprecated 1.9 Use remove()
180
	 */
181
	public function del($key) {
182
		elgg_deprecated_notice(__METHOD__ . " has been deprecated.", 1.9);
183
		$this->remove($key);
184
	}
185
186
	/**
187
	 * Has the attribute been defined
188
	 *
189
	 * @param string $name Name of the attribute
190
	 * @return bool
191
	 * @since 1.9
192
	 */
193 3
	public function has($name) {
194 3
		return $this->storage->has($name);
195
	}
196
197
	/**
198
	 * Sets the logged in user
199
	 * 
200
	 * @param \ElggUser $user The user who is logged in
201
	 * @return void
202
	 * @since 1.9
203
	 */
204
	public function setLoggedInUser(\ElggUser $user) {
205
		$this->set('guid', $user->guid);
206
		$this->logged_in_user = $user;
207
	}
208
209
	/**
210
	 * Gets the logged in user
211
	 * 
212
	 * @return \ElggUser
213
	 * @since 1.9
214
	 */
215 37
	public function getLoggedInUser() {
216 37
		return $this->logged_in_user;
217
	}
218
219
	/**
220
	 * Return the current logged in user by guid.
221
	 *
222
	 * @see elgg_get_logged_in_user_entity()
223
	 * @return int
224
	 */
225 32
	public function getLoggedInUserGuid() {
226 32
		$user = $this->getLoggedInUser();
227 32
		return $user ? $user->guid : 0;
228
	}
229
	
230
	/**
231
	 * Returns whether or not the viewer is currently logged in and an admin user.
232
	 *
233
	 * @return bool
234
	 */
235
	public function isAdminLoggedIn() {
236
		$user = $this->getLoggedInUser();
237
	
238
		return $user && $user->isAdmin();
239
	}
240
	
241
	/**
242
	 * Returns whether or not the user is currently logged in
243
	 *
244
	 * @return bool
245
	 */
246
	public function isLoggedIn() {
247
		return (bool)$this->getLoggedInUser();
248
	}
249
250
	/**
251
	 * Remove the logged in user
252
	 * 
253
	 * @return void
254
	 * @since 1.9
255
	 */
256
	public function removeLoggedInUser() {
257
		$this->logged_in_user = null;
258
		$this->remove('guid');
259
	}
260
261
	/**
262
	 * Get current ignore access setting.
263
	 *
264
	 * @return bool
265
	 */
266
	public function getIgnoreAccess() {
267
		return $this->ignore_access;
268
	}
269
270
	/**
271
	 * Set ignore access.
272
	 *
273
	 * @param bool $ignore Ignore access
274
	 *
275
	 * @return bool Previous setting
276
	 */
277 3
	public function setIgnoreAccess($ignore = true) {
278 3
		_elgg_services()->accessCache->clear();
279
280 3
		$prev = $this->ignore_access;
281 3
		$this->ignore_access = $ignore;
282
283 3
		return $prev;
284
	}
285
286
	// @codingStandardsIgnoreStart
287
	/**
288
	 * Alias of getIgnoreAccess()
289
	 *
290
	 * @todo remove with elgg_get_access_object()
291
	 *
292
	 * @return bool
293
	 * @deprecated 1.8 Use elgg_get_ignore_access()
294
	 */
295
	public function get_ignore_access() {
296
		return $this->getIgnoreAccess();
297
	}
298
	// @codingStandardsIgnoreEnd
299
300
	// @codingStandardsIgnoreStart
301
	/**
302
	 * Alias of setIgnoreAccess()
303
	 *
304
	 * @todo remove with elgg_get_access_object()
305
	 *
306
	 * @param bool $ignore Ignore access
307
	 *
308
	 * @return bool Previous setting
309
	 *
310
	 * @deprecated 1.8 Use elgg_set_ignore_access()
311
	 */
312
	public function set_ignore_access($ignore = true) {
313
		return $this->setIgnoreAccess($ignore);
314
	}
315
	// @codingStandardsIgnoreEnd
316
317
	/**
318
	 * Adds a token to the session
319
	 * 
320
	 * This is used in creation of CSRF token, and is passed to the client to allow validating tokens
321
	 * later, even if the PHP session was destroyed.
322
	 * 
323
	 * @return void
324
	 */
325 3
	protected function generateSessionToken() {
326
		// Generate a simple token that we store server side
327 3
		if (!$this->has('__elgg_session')) {
328 3
			$this->set('__elgg_session', _elgg_services()->crypto->getRandomString(22));
329 3
		}
330 3
	}
331
332
	/**
333
	 * Test if property is set either as an attribute or metadata.
334
	 *
335
	 * @param string $key The name of the attribute or metadata.
336
	 *
337
	 * @return bool
338
	 * @deprecated 1.9 Use has()
339
	 */
340
	public function __isset($key) {
341
		elgg_deprecated_notice(__METHOD__ . " has been deprecated.", 1.9);
342
		// Note: We use offsetExists() for BC
343
		return $this->offsetExists($key);
0 ignored issues
show
Deprecated Code introduced by
The method ElggSession::offsetExists() has been deprecated with message: 1.9 Use has()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
344
	}
345
346
	/**
347
	 * Set a value, go straight to session.
348
	 *
349
	 * @param string $key   Name
350
	 * @param mixed  $value Value
351
	 *
352
	 * @return void
353
	 * @deprecated 1.9 Use set()
354
	 */
355
	public function offsetSet($key, $value) {
356
		elgg_deprecated_notice(__METHOD__ . " has been deprecated.", 1.9);
357
		$this->set($key, $value);
358
	}
359
360
	/**
361
	 * Get a variable from either the session, or if its not in the session
362
	 * attempt to get it from an api call.
363
	 *
364
	 * @see \ArrayAccess::offsetGet()
365
	 *
366
	 * @param mixed $key Name
367
	 *
368
	 * @return mixed
369
	 * @deprecated 1.9 Use get()
370
	 */
371
	public function offsetGet($key) {
372
		elgg_deprecated_notice(__METHOD__ . " has been deprecated.", 1.9);
373
374
		if (in_array($key, array('user', 'id', 'name', 'username'))) {
375
			elgg_deprecated_notice("Only 'guid' is stored in session for user now", 1.9);
376
			if ($this->logged_in_user) {
377
				switch ($key) {
378
					case 'user':
379
						return $this->logged_in_user;
380
						break;
0 ignored issues
show
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
381
					case 'id':
382
						return $this->logged_in_user->guid;
383
						break;
0 ignored issues
show
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
384
					case 'name':
385
					case 'username':
386
						return $this->logged_in_user->$key;
387
						break;
0 ignored issues
show
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
388
				}
389
			} else {
390
				return null;
391
			}
392
		}
393
394
		if ($this->has($key)) {
395
			return $this->get($key);
396
		}
397
398
		$orig_value = null;
399
		$value = _elgg_services()->hooks->trigger('session:get', $key, null, $orig_value);
400
		if ($orig_value !== $value) {
401
			elgg_deprecated_notice("Plugin hook session:get has been deprecated.", 1.9);
402
		}
403
404
		$this->set($key, $value);
405
		return $value;
406
	}
407
408
	/**
409
	 * Unset a value from the cache and the session.
410
	 *
411
	 * @see \ArrayAccess::offsetUnset()
412
	 *
413
	 * @param mixed $key Name
414
	 *
415
	 * @return void
416
	 * @deprecated 1.9 Use remove()
417
	 */
418
	public function offsetUnset($key) {
419
		elgg_deprecated_notice(__METHOD__ . " has been deprecated.", 1.9);
420
		$this->remove($key);
421
	}
422
423
	/**
424
	 * Return whether the value is set in either the session or the cache.
425
	 *
426
	 * @see \ArrayAccess::offsetExists()
427
	 *
428
	 * @param int $offset Offset
429
	 *
430
	 * @return bool
431
	 * @deprecated 1.9 Use has()
432
	 */
433
	public function offsetExists($offset) {
434
		elgg_deprecated_notice(__METHOD__ . " has been deprecated.", 1.9);
435
436
		if (in_array($offset, array('user', 'id', 'name', 'username'))) {
437
			elgg_deprecated_notice("Only 'guid' is stored in session for user now", 1.9);
438
			return (bool)$this->logged_in_user;
439
		}
440
441
		if ($this->has($offset)) {
442
			return true;
443
		}
444
445
		// Note: We use offsetGet() for BC
446
		if ($this->offsetGet($offset)) {
0 ignored issues
show
Deprecated Code introduced by
The method ElggSession::offsetGet() has been deprecated with message: 1.9 Use get()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
447
			return true;
448
		}
449
450
		return false;
451
	}
452
453
	/**
454
	 * Get an isolated ElggSession that does not persist between requests
455
	 *
456
	 * @return self
457
	 */
458 79
	public static function getMock() {
459 79
		$storage = new MockArraySessionStorage();
460 79
		$session = new Session($storage);
461 79
		return new self($session);
462
	}
463
}
464