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.
1 | <?php |
||
2 | /** |
||
3 | * Handle data for the current customers session. |
||
4 | * Implements the WPInv_Session abstract class. |
||
5 | * |
||
6 | */ |
||
7 | |||
8 | defined( 'ABSPATH' ) || exit; |
||
9 | |||
10 | /** |
||
11 | * Session handler class. |
||
12 | * |
||
13 | * @deprecated |
||
14 | */ |
||
15 | class WPInv_Session_Handler extends WPInv_Session { |
||
16 | |||
17 | /** |
||
18 | * Cookie name used for the session. |
||
19 | * |
||
20 | * @var string cookie name |
||
21 | */ |
||
22 | protected $_cookie; |
||
23 | |||
24 | /** |
||
25 | * Stores session expiry. |
||
26 | * |
||
27 | * @var int session due to expire timestamp |
||
28 | */ |
||
29 | protected $_session_expiring; |
||
30 | |||
31 | /** |
||
32 | * Stores session due to expire timestamp. |
||
33 | * |
||
34 | * @var string session expiration timestamp |
||
35 | */ |
||
36 | protected $_session_expiration; |
||
37 | |||
38 | /** |
||
39 | * True when the cookie exists. |
||
40 | * |
||
41 | * @var bool Based on whether a cookie exists. |
||
42 | */ |
||
43 | protected $_has_cookie = false; |
||
44 | |||
45 | /** |
||
46 | * Table name for session data. |
||
47 | * |
||
48 | * @var string Custom session table name |
||
49 | */ |
||
50 | protected $_table; |
||
51 | |||
52 | /** |
||
53 | * Constructor for the session class. |
||
54 | */ |
||
55 | public function old__construct() { |
||
56 | |||
57 | $this->_cookie = apply_filters( 'wpinv_cookie', 'wpinv_session_' . COOKIEHASH ); |
||
58 | add_action( 'init', array( $this, 'init' ), -1 ); |
||
59 | add_action( 'wp_logout', array( $this, 'destroy_session' ) ); |
||
60 | add_action( 'wp', array( $this, 'set_customer_session_cookie' ), 10 ); |
||
61 | add_action( 'shutdown', array( $this, 'save_data' ), 20 ); |
||
62 | |||
63 | } |
||
64 | |||
65 | /** |
||
66 | * Init hooks and session data. |
||
67 | * |
||
68 | * @since 3.3.0 |
||
69 | */ |
||
70 | public function init() { |
||
71 | $this->init_session_cookie(); |
||
72 | |||
73 | if ( ! is_user_logged_in() ) { |
||
74 | add_filter( 'nonce_user_logged_out', array( $this, 'nonce_user_logged_out' ), 10, 2 ); |
||
75 | } |
||
76 | } |
||
77 | |||
78 | /** |
||
79 | * Setup cookie and customer ID. |
||
80 | * |
||
81 | * @since 3.6.0 |
||
82 | */ |
||
83 | public function init_session_cookie() { |
||
84 | $cookie = $this->get_session_cookie(); |
||
85 | |||
86 | if ( $cookie ) { |
||
87 | $this->_customer_id = $cookie[0]; |
||
0 ignored issues
–
show
|
|||
88 | $this->_session_expiration = $cookie[1]; |
||
89 | $this->_session_expiring = $cookie[2]; |
||
0 ignored issues
–
show
The property
$_session_expiring was declared of type integer , but $cookie[2] is of type string . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
90 | $this->_has_cookie = true; |
||
91 | $this->_data = $this->get_session_data(); |
||
92 | |||
93 | // If the user logs in, update session. |
||
94 | if ( is_user_logged_in() && get_current_user_id() != $this->_customer_id ) { |
||
95 | $this->_customer_id = get_current_user_id(); |
||
96 | $this->_dirty = true; |
||
97 | $this->save_data(); |
||
98 | $this->set_customer_session_cookie( true ); |
||
99 | } |
||
100 | |||
101 | // Update session if its close to expiring. |
||
102 | if ( time() > $this->_session_expiring ) { |
||
103 | $this->set_session_expiration(); |
||
104 | $this->update_session_timestamp( $this->_customer_id, $this->_session_expiration ); |
||
105 | } |
||
106 | } else { |
||
107 | $this->set_session_expiration(); |
||
108 | $this->_customer_id = $this->generate_customer_id(); |
||
109 | $this->_data = $this->get_session_data(); |
||
110 | } |
||
111 | } |
||
112 | |||
113 | /** |
||
114 | * Sets the session cookie on-demand (usually after adding an item to the cart). |
||
115 | * |
||
116 | * Since the cookie name (as of 2.1) is prepended with wp, cache systems like batcache will not cache pages when set. |
||
117 | * |
||
118 | * Warning: Cookies will only be set if this is called before the headers are sent. |
||
119 | * |
||
120 | * @param bool $set Should the session cookie be set. |
||
121 | */ |
||
122 | public function set_customer_session_cookie( $set ) { |
||
123 | if ( $set ) { |
||
124 | $to_hash = $this->_customer_id . '|' . $this->_session_expiration; |
||
125 | $cookie_hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) ); |
||
126 | $cookie_value = $this->_customer_id . '||' . $this->_session_expiration . '||' . $this->_session_expiring . '||' . $cookie_hash; |
||
127 | $this->_has_cookie = true; |
||
128 | |||
129 | if ( ! isset( $_COOKIE[ $this->_cookie ] ) || $_COOKIE[ $this->_cookie ] !== $cookie_value ) { |
||
130 | $this->setcookie( $this->_cookie, $cookie_value, $this->_session_expiration, $this->use_secure_cookie(), true ); |
||
131 | } |
||
132 | } |
||
133 | } |
||
134 | |||
135 | public function setcookie( $name, $value, $expire = 0, $secure = false, $httponly = false ) { |
||
136 | if ( ! headers_sent() ) { |
||
137 | setcookie( $name, $value, $expire, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN, $secure, apply_filters( 'wpinv_cookie_httponly', $httponly, $name, $value, $expire, $secure ) ); |
||
138 | } elseif ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { |
||
139 | headers_sent( $file, $line ); |
||
140 | trigger_error( "{$name} cookie cannot be set - headers already sent by {$file} on line {$line}", E_USER_NOTICE ); // @codingStandardsIgnoreLine |
||
141 | } |
||
142 | } |
||
143 | |||
144 | /** |
||
145 | * Should the session cookie be secure? |
||
146 | * |
||
147 | * @since 3.6.0 |
||
148 | * @return bool |
||
149 | */ |
||
150 | protected function use_secure_cookie() { |
||
151 | $is_https = false !== strstr( get_option( 'home' ), 'https:' ); |
||
152 | return apply_filters( 'wpinv_session_use_secure_cookie', $is_https && is_ssl() ); |
||
153 | } |
||
154 | |||
155 | /** |
||
156 | * Return true if the current user has an active session, i.e. a cookie to retrieve values. |
||
157 | * |
||
158 | * @return bool |
||
159 | */ |
||
160 | public function has_session() { |
||
161 | return isset( $_COOKIE[ $this->_cookie ] ) || $this->_has_cookie || is_user_logged_in(); // @codingStandardsIgnoreLine. |
||
162 | } |
||
163 | |||
164 | /** |
||
165 | * Set session expiration. |
||
166 | */ |
||
167 | public function set_session_expiration() { |
||
168 | $this->_session_expiring = time() + intval( apply_filters( 'wpinv_session_expiring', 60 * 60 * 47 ) ); // 47 Hours. |
||
169 | $this->_session_expiration = time() + intval( apply_filters( 'wpinv_session_expiration', 60 * 60 * 48 ) ); // 48 Hours. |
||
170 | } |
||
171 | |||
172 | /** |
||
173 | * Generates session ids. |
||
174 | * |
||
175 | * @return string |
||
176 | */ |
||
177 | public function generate_customer_id() { |
||
178 | require_once ABSPATH . 'wp-includes/class-phpass.php'; |
||
179 | $hasher = new PasswordHash( 8, false ); |
||
180 | return md5( $hasher->get_random_bytes( 32 ) ); |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * Get the session cookie, if set. Otherwise return false. |
||
185 | * |
||
186 | * Session cookies without a customer ID are invalid. |
||
187 | * |
||
188 | * @return bool|array |
||
189 | */ |
||
190 | public function get_session_cookie() { |
||
191 | $cookie_value = isset( $_COOKIE[ $this->_cookie ] ) ? wp_unslash( $_COOKIE[ $this->_cookie ] ) : false; // @codingStandardsIgnoreLine. |
||
192 | |||
193 | if ( empty( $cookie_value ) || ! is_string( $cookie_value ) ) { |
||
194 | return false; |
||
195 | } |
||
196 | |||
197 | list( $customer_id, $session_expiration, $session_expiring, $cookie_hash ) = explode( '||', $cookie_value ); |
||
198 | |||
199 | if ( empty( $customer_id ) ) { |
||
200 | return false; |
||
201 | } |
||
202 | |||
203 | // Validate hash. |
||
204 | $to_hash = $customer_id . '|' . $session_expiration; |
||
205 | $hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) ); |
||
206 | |||
207 | if ( empty( $cookie_hash ) || ! hash_equals( $hash, $cookie_hash ) ) { |
||
208 | return false; |
||
209 | } |
||
210 | |||
211 | return array( $customer_id, $session_expiration, $session_expiring, $cookie_hash ); |
||
212 | } |
||
213 | |||
214 | /** |
||
215 | * Get session data. |
||
216 | * |
||
217 | * @return array |
||
218 | */ |
||
219 | public function get_session_data() { |
||
220 | return $this->has_session() ? (array) $this->get_session( $this->_customer_id ) : array(); |
||
221 | } |
||
222 | |||
223 | public function generate_key( $customer_id ) { |
||
224 | if ( ! $customer_id ) { |
||
225 | return; |
||
226 | } |
||
227 | |||
228 | return 'wpi_trans_' . $customer_id; |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * Save data. |
||
233 | */ |
||
234 | public function save_data() { |
||
235 | // Dirty if something changed - prevents saving nothing new. |
||
236 | if ( $this->_dirty && $this->has_session() ) { |
||
237 | |||
238 | set_transient( $this->generate_key( $this->_customer_id ), $this->_data, $this->_session_expiration ); |
||
239 | |||
240 | $this->_dirty = false; |
||
241 | } |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * Destroy all session data. |
||
246 | */ |
||
247 | public function destroy_session() { |
||
248 | $this->delete_session( $this->_customer_id ); |
||
249 | $this->forget_session(); |
||
250 | } |
||
251 | |||
252 | /** |
||
253 | * Forget all session data without destroying it. |
||
254 | */ |
||
255 | public function forget_session() { |
||
256 | $this->setcookie( $this->_cookie, '', time() - YEAR_IN_SECONDS, $this->use_secure_cookie(), true ); |
||
257 | |||
258 | wpinv_empty_cart(); |
||
259 | |||
260 | $this->_data = array(); |
||
261 | $this->_dirty = false; |
||
262 | $this->_customer_id = $this->generate_customer_id(); |
||
0 ignored issues
–
show
The property
$_customer_id was declared of type integer , but $this->generate_customer_id() is of type string . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
263 | } |
||
264 | |||
265 | /** |
||
266 | * When a user is logged out, ensure they have a unique nonce by using the customer/session ID. |
||
267 | * |
||
268 | * @param int $uid User ID. |
||
269 | * @return string |
||
270 | */ |
||
271 | public function nonce_user_logged_out( $uid ) { |
||
272 | |||
273 | // Check if one of our nonces. |
||
274 | if ( substr( $uid, 0, 5 ) === 'wpinv' || substr( $uid, 0, 7 ) === 'getpaid' ) { |
||
275 | return $this->has_session() && $this->_customer_id ? $this->_customer_id : $uid; |
||
276 | } |
||
277 | |||
278 | return $uid; |
||
279 | } |
||
280 | |||
281 | /** |
||
282 | * Returns the session. |
||
283 | * |
||
284 | * @param string $customer_id Customer ID. |
||
285 | * @param mixed $default Default session value. |
||
286 | * @return string|array |
||
287 | */ |
||
288 | public function get_session( $customer_id, $default = false ) { |
||
289 | |||
290 | if ( defined( 'WP_SETUP_CONFIG' ) ) { |
||
291 | return array(); |
||
292 | } |
||
293 | |||
294 | $key = $this->generate_key( $customer_id ); |
||
295 | $value = get_transient( $key ); |
||
296 | |||
297 | if ( ! $value ) { |
||
298 | $value = $default; |
||
299 | } |
||
300 | |||
301 | return maybe_unserialize( $value ); |
||
302 | } |
||
303 | |||
304 | /** |
||
305 | * Delete the session from the cache and database. |
||
306 | * |
||
307 | * @param int $customer_id Customer ID. |
||
308 | */ |
||
309 | public function delete_session( $customer_id ) { |
||
310 | |||
311 | $key = $this->generate_key( $customer_id ); |
||
312 | |||
313 | delete_transient( $key ); |
||
314 | } |
||
315 | |||
316 | /** |
||
317 | * Update the session expiry timestamp. |
||
318 | * |
||
319 | * @param string $customer_id Customer ID. |
||
320 | * @param int $timestamp Timestamp to expire the cookie. |
||
321 | */ |
||
322 | public function update_session_timestamp( $customer_id, $timestamp ) { |
||
323 | |||
324 | set_transient( $this->generate_key( $customer_id ), maybe_serialize( $this->_data ), $timestamp ); |
||
325 | |||
326 | } |
||
327 | } |
||
328 |
This check looks for assignments to scalar types that may be of the wrong type.
To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.