PluginProbe
Plugin Detective – Troubleshooting Conflicts / 1.2.35
Plugin Detective – Troubleshooting Conflicts v1.2.35
1.2.35 1.2.33 1.2.32 1.2.31 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.2 1.2.1 1.2.10 1.2.12 1.2.13 1.2.14 1.2.16 1.2.19 1.2.20 1.2.22 1.2.23 1.2.24 All 54 releases
← All changes | troubleshoot/includes/class-api.php +18 -17 1.2 → 1.2.35 View file →
@@ -115,10 +115,10 @@
115 115
116 116 public function process_input() {
117 117 $this->request = array();
118 118
119 - if ( !empty( $_REQUEST ) ) {
120 - $this->request = $_REQUEST;
119 + if ( ! empty( $_REQUEST ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Custom troubleshooter API authenticated via PDT_Auth nonce; runs standalone when the WP REST API is unavailable.
120 + $this->request = $_REQUEST; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- See above; params validated downstream in process_params().
121 121 }
122 122
123 123 $json = file_get_contents("php://input");
124 124 if ( empty( $json ) ) {
@@ -163,26 +163,18 @@
163 163 }
164 164
165 165 // Authentication Request
166 166 if ( $this->params['action'] == 'authenticate' ) {
167 - $auth_response = $this->plugin->auth->get_nonce( $this->params['username'], $this->params['password'], 'pd_api' );
167 + $user = $this->plugin->auth->authenticate( $this->params['username'], $this->params['password'] );
168 168
169 - if ( is_a( $auth_response, 'WP_Error' ) ) {
170 - $this->errors['authentication'] = array_keys( $auth_response->errors );
171 - $this->errors['authentication'] = $this->errors['authentication']['0'];
169 + if ( is_a( $user, 'WP_Error' ) ) {
170 + // Single, fixed error code for every failure mode — never echo a
171 + // code that distinguishes a valid username from an invalid one.
172 + $this->errors['authentication'] = $user->get_error_code();
172 173 } else {
173 - $this->data['nonce'] = $auth_response;
174 + $this->data['nonce'] = $this->plugin->auth->create_nonce( 'pd_api', $user->ID );
174 175 }
175 176
176 - $user_response = $this->plugin->auth->get_user( $this->params['username'], $this->params['password'], 'pd_api' );
177 -
178 - if ( is_a( $user_response, 'WP_Error' ) ) {
179 - $this->errors['authentication'] = array_keys( $user_response->errors );
180 - $this->errors['authentication'] = $this->errors['authentication']['0'];
181 - } else {
182 - $this->data['user'] = $user_response;
183 - }
184 -
185 177 $this->return_response();
186 178 }
187 179
188 180
@@ -191,10 +183,19 @@
191 183 $this->errors['nonce'] = 'Required for authenticated requests';
192 184 $this->return_response();
193 185 }
194 186
195 - if ( ! $this->plugin->auth->verify_nonce( $this->params['nonce'], 'pd_api' ) ) {
187 + $nonce_user_id = $this->plugin->auth->verify_nonce( $this->params['nonce'], 'pd_api' );
188 + if ( empty( $nonce_user_id ) ) {
196 189 $this->errors['nonce'] = 'Invalid';
190 + $this->return_response();
191 + }
192 +
193 + // The nonce is bound to the user it was issued for. Re-check that user still
194 + // has plugin-management rights so a token can never authorize more than its
195 + // owner, even if it leaks or the user's role is later downgraded.
196 + if ( ! user_can( $nonce_user_id, 'activate_plugins' ) ) {
197 + $this->errors['permission'] = 'You do not have permission to perform this action';
197 198 $this->return_response();
198 199 }
199 200
200 201