Issues (4967)

Security Analysis    not enabled

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.

src/wp-includes/class-wp-session-tokens.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
 * Session API: WP_Session_Tokens class
4
 *
5
 * @package WordPress
6
 * @subpackage Session
7
 * @since 4.7.0
8
 */
9
10
/**
11
 * Abstract class for managing user session tokens.
12
 *
13
 * @since 4.0.0
14
 */
15
abstract class WP_Session_Tokens {
16
17
	/**
18
	 * User ID.
19
	 *
20
	 * @since 4.0.0
21
	 * @access protected
22
	 * @var int User ID.
23
	 */
24
	protected $user_id;
25
26
	/**
27
	 * Protected constructor.
28
	 *
29
	 * @since 4.0.0
30
	 *
31
	 * @param int $user_id User whose session to manage.
32
	 */
33
	protected function __construct( $user_id ) {
34
		$this->user_id = $user_id;
35
	}
36
37
	/**
38
	 * Get a session token manager instance for a user.
39
	 *
40
	 * This method contains a filter that allows a plugin to swap out
41
	 * the session manager for a subclass of WP_Session_Tokens.
42
	 *
43
	 * @since 4.0.0
44
	 * @access public
45
	 * @static
46
	 *
47
	 * @param int $user_id User whose session to manage.
48
	 */
49
	final public static function get_instance( $user_id ) {
50
		/**
51
		 * Filters the session token manager used.
52
		 *
53
		 * @since 4.0.0
54
		 *
55
		 * @param string $session Name of class to use as the manager.
56
		 *                        Default 'WP_User_Meta_Session_Tokens'.
57
		 */
58
		$manager = apply_filters( 'session_token_manager', 'WP_User_Meta_Session_Tokens' );
59
		return new $manager( $user_id );
60
	}
61
62
	/**
63
	 * Hashes a session token for storage.
64
	 *
65
	 * @since 4.0.0
66
	 * @access private
67
	 *
68
	 * @param string $token Session token to hash.
69
	 * @return string A hash of the session token (a verifier).
70
	 */
71
	final private function hash_token( $token ) {
72
		// If ext/hash is not present, use sha1() instead.
73
		if ( function_exists( 'hash' ) ) {
74
			return hash( 'sha256', $token );
75
		} else {
76
			return sha1( $token );
77
		}
78
	}
79
80
	/**
81
	 * Get a user's session.
82
	 *
83
	 * @since 4.0.0
84
	 * @access public
85
	 *
86
	 * @param string $token Session token
87
	 * @return array User session
0 ignored issues
show
Should the return type not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
88
	 */
89
	final public function get( $token ) {
90
		$verifier = $this->hash_token( $token );
91
		return $this->get_session( $verifier );
92
	}
93
94
	/**
95
	 * Validate a user's session token as authentic.
96
	 *
97
	 * Checks that the given token is present and hasn't expired.
98
	 *
99
	 * @since 4.0.0
100
	 * @access public
101
	 *
102
	 * @param string $token Token to verify.
103
	 * @return bool Whether the token is valid for the user.
104
	 */
105
	final public function verify( $token ) {
106
		$verifier = $this->hash_token( $token );
107
		return (bool) $this->get_session( $verifier );
108
	}
109
110
	/**
111
	 * Generate a session token and attach session information to it.
112
	 *
113
	 * A session token is a long, random string. It is used in a cookie
114
	 * link that cookie to an expiration time and to ensure the cookie
115
	 * becomes invalidated upon logout.
116
	 *
117
	 * This function generates a token and stores it with the associated
118
	 * expiration time (and potentially other session information via the
119
	 * {@see 'attach_session_information'} filter).
120
	 *
121
	 * @since 4.0.0
122
	 * @access public
123
	 *
124
	 * @param int $expiration Session expiration timestamp.
125
	 * @return string Session token.
126
	 */
127
	final public function create( $expiration ) {
128
		/**
129
		 * Filters the information attached to the newly created session.
130
		 *
131
		 * Could be used in the future to attach information such as
132
		 * IP address or user agent to a session.
133
		 *
134
		 * @since 4.0.0
135
		 *
136
		 * @param array $session Array of extra data.
137
		 * @param int   $user_id User ID.
138
		 */
139
		$session = apply_filters( 'attach_session_information', array(), $this->user_id );
140
		$session['expiration'] = $expiration;
141
142
		// IP address.
143
		if ( !empty( $_SERVER['REMOTE_ADDR'] ) ) {
144
			$session['ip'] = $_SERVER['REMOTE_ADDR'];
145
		}
146
147
		// User-agent.
148
		if ( ! empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
149
			$session['ua'] = wp_unslash( $_SERVER['HTTP_USER_AGENT'] );
150
		}
151
152
		// Timestamp
153
		$session['login'] = time();
154
155
		$token = wp_generate_password( 43, false, false );
156
157
		$this->update( $token, $session );
158
159
		return $token;
160
	}
161
162
	/**
163
	 * Update a session token.
164
	 *
165
	 * @since 4.0.0
166
	 * @access public
167
	 *
168
	 * @param string $token Session token to update.
169
	 * @param array  $session Session information.
170
	 */
171
	final public function update( $token, $session ) {
172
		$verifier = $this->hash_token( $token );
173
		$this->update_session( $verifier, $session );
174
	}
175
176
	/**
177
	 * Destroy a session token.
178
	 *
179
	 * @since 4.0.0
180
	 * @access public
181
	 *
182
	 * @param string $token Session token to destroy.
183
	 */
184
	final public function destroy( $token ) {
185
		$verifier = $this->hash_token( $token );
186
		$this->update_session( $verifier, null );
187
	}
188
189
	/**
190
	 * Destroy all session tokens for this user,
191
	 * except a single token, presumably the one in use.
192
	 *
193
	 * @since 4.0.0
194
	 * @access public
195
	 *
196
	 * @param string $token_to_keep Session token to keep.
197
	 */
198
	final public function destroy_others( $token_to_keep ) {
199
		$verifier = $this->hash_token( $token_to_keep );
200
		$session = $this->get_session( $verifier );
201
		if ( $session ) {
202
			$this->destroy_other_sessions( $verifier );
203
		} else {
204
			$this->destroy_all_sessions();
205
		}
206
	}
207
208
	/**
209
	 * Determine whether a session token is still valid,
210
	 * based on expiration.
211
	 *
212
	 * @since 4.0.0
213
	 * @access protected
214
	 *
215
	 * @param array $session Session to check.
216
	 * @return bool Whether session is valid.
217
	 */
218
	final protected function is_still_valid( $session ) {
219
		return $session['expiration'] >= time();
220
	}
221
222
	/**
223
	 * Destroy all session tokens for a user.
224
	 *
225
	 * @since 4.0.0
226
	 * @access public
227
	 */
228
	final public function destroy_all() {
229
		$this->destroy_all_sessions();
230
	}
231
232
	/**
233
	 * Destroy all session tokens for all users.
234
	 *
235
	 * @since 4.0.0
236
	 * @access public
237
	 * @static
238
	 */
239
	final public static function destroy_all_for_all_users() {
240
		/** This filter is documented in wp-includes/class-wp-session-tokens.php */
241
		$manager = apply_filters( 'session_token_manager', 'WP_User_Meta_Session_Tokens' );
242
		call_user_func( array( $manager, 'drop_sessions' ) );
243
	}
244
245
	/**
246
	 * Retrieve all sessions of a user.
247
	 *
248
	 * @since 4.0.0
249
	 * @access public
250
	 *
251
	 * @return array Sessions of a user.
252
	 */
253
	final public function get_all() {
254
		return array_values( $this->get_sessions() );
255
	}
256
257
	/**
258
	 * This method should retrieve all sessions of a user, keyed by verifier.
259
	 *
260
	 * @since 4.0.0
261
	 * @access protected
262
	 *
263
	 * @return array Sessions of a user, keyed by verifier.
264
	 */
265
	abstract protected function get_sessions();
266
267
	/**
268
	 * This method should look up a session by its verifier (token hash).
269
	 *
270
	 * @since 4.0.0
271
	 * @access protected
272
	 *
273
	 * @param string $verifier Verifier of the session to retrieve.
274
	 * @return array|null The session, or null if it does not exist.
275
	 */
276
	abstract protected function get_session( $verifier );
277
278
	/**
279
	 * This method should update a session by its verifier.
280
	 *
281
	 * Omitting the second argument should destroy the session.
282
	 *
283
	 * @since 4.0.0
284
	 * @access protected
285
	 *
286
	 * @param string $verifier Verifier of the session to update.
287
	 * @param array  $session  Optional. Session. Omitting this argument destroys the session.
0 ignored issues
show
Should the type for parameter $session not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
288
	 */
289
	abstract protected function update_session( $verifier, $session = null );
0 ignored issues
show
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
290
291
	/**
292
	 * This method should destroy all session tokens for this user,
293
	 * except a single session passed.
294
	 *
295
	 * @since 4.0.0
296
	 * @access protected
297
	 *
298
	 * @param string $verifier Verifier of the session to keep.
299
	 */
300
	abstract protected function destroy_other_sessions( $verifier );
0 ignored issues
show
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
301
302
	/**
303
	 * This method should destroy all sessions for a user.
304
	 *
305
	 * @since 4.0.0
306
	 * @access protected
307
	 */
308
	abstract protected function destroy_all_sessions();
0 ignored issues
show
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
309
310
	/**
311
	 * This static method should destroy all session tokens for all users.
312
	 *
313
	 * @since 4.0.0
314
	 * @access public
315
	 * @static
316
	 */
317
	public static function drop_sessions() {}
318
}
319