PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 3.3.1
WP STAGING – WordPress Backup, Restore, Migration & Clone v3.3.1
4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Framework / Security / AccessToken.php
wp-staging / Framework / Security Last commit date
AccessToken.php 2 years ago Auth.php 2 years ago Capabilities.php 2 years ago DataEncryption.php 2 years ago Nonce.php 3 years ago UniqueIdentifier.php 3 years ago
AccessToken.php
127 lines
1 <?php
2
3 namespace WPStaging\Framework\Security;
4
5 /**
6 * Class AccessToken
7 *
8 * WPSTAGING own implementation of a WordPress nonce,
9 * with the difference that it's generated and invalidated
10 * under our own criteria.
11 *
12 * @package WPStaging\Framework\Security
13 */
14 class AccessToken
15 {
16 /**
17 * The key in $_REQUEST that AccessToken expects to find a token.
18 */
19 const REQUEST_KEY = 'accessToken';
20
21 /**
22 * The option_name that is stored in the database.
23 */
24 const OPTION_NAME = 'wpstg_access_token';
25
26 /**
27 * @return bool Whether the current $_REQUEST has a valid token.
28 */
29 public function requestHasValidToken()
30 {
31 return isset($_REQUEST[self::REQUEST_KEY]) && $this->isValidToken(sanitize_text_field($_REQUEST[self::REQUEST_KEY]));
32 }
33
34 /**
35 * @return string The new access token
36 * @return string|bool Returns False if user has no cap to generate a new token,
37 * or the generated token does not comply with the standards.
38 */
39 public function generateNewToken()
40 {
41 // Early bail: Not enough privilege to generate a token. Todo: Remove "new" once we have DI
42 if (! current_user_can((new Capabilities())->manageWPSTG())) {
43 return false;
44 }
45
46 $newToken = wp_generate_password(64, false);
47
48 // Early bail: A token is always a 64-character random string.
49 if (strlen($newToken) !== 64) {
50 return false;
51 }
52
53 /* literals that start with 0x are hexadecimal integers (base 16) and can lead to blocked requests by mod_security
54 * Issue: https://github.com/wp-staging/wp-staging-pro/issues/1650
55 */
56 $sanitizedToken = str_ireplace('0x', 'ax', $newToken);
57
58 update_option(static::OPTION_NAME, $sanitizedToken);
59
60 return $sanitizedToken;
61 }
62
63 /**
64 * @param string $newToken The new token, a 64-char string.
65 *
66 * @return false|mixed
67 */
68 public function setToken($newToken)
69 {
70 // Early bail: Not enough privilege to generate a token.
71 if (! current_user_can((new Capabilities())->manageWPSTG())) {
72 return false;
73 }
74
75 // Early bail: A token is always a 64-character random string.
76 if (strlen($newToken) !== 64) {
77 return false;
78 }
79
80 update_option(static::OPTION_NAME, $newToken);
81
82 return $newToken;
83 }
84
85 /**
86 * Gets the token. Requires user to be logged-in.
87 *
88 * @return string The access token or an empty string if no token exists.
89 * @return string|bool Returns False if user has no cap to read the token.
90 */
91 public function getToken()
92 {
93 // Early bail: Not enough privilege to get a token. Todo: Remove "new" once we have DI
94 if (! current_user_can((new Capabilities())->manageWPSTG())) {
95 return false;
96 }
97
98 return (string)get_option(static::OPTION_NAME, null);
99 }
100
101 /**
102 * Check if given token is valid. Does not require user to be logged-in.
103 *
104 * @param string $tokenToValidate A token to compare with the saved token.
105 *
106 * @return bool Whether given token is valid.
107 */
108 public function isValidToken($tokenToValidate)
109 {
110 $tokenToValidate = (string)$tokenToValidate;
111
112 // Early bail: A token is always a 64-character random string.
113 if (empty($tokenToValidate) || strlen($tokenToValidate) !== 64) {
114 return false;
115 }
116
117 $savedToken = (string)get_option(static::OPTION_NAME, null);
118
119 // Early bail: We can't validate a token because at least one of the parts are empty.
120 if (empty($savedToken)) {
121 return false;
122 }
123
124 return $tokenToValidate === $savedToken;
125 }
126 }
127