PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.0-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.0-beta
16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / modules / sharedaddy / recaptcha.php
jetpack / modules / sharedaddy Last commit date
images 2 months ago services 7 months ago admin-sharing-rtl.css 4 months ago admin-sharing-rtl.min.css 1 month ago admin-sharing.css 4 months ago admin-sharing.js 2 months ago admin-sharing.min.css 1 month ago amp-sharing.css 4 months ago recaptcha.php 1 month ago sharedaddy.php 7 months ago sharing-service.php 1 month ago sharing-sources.php 1 month ago sharing.css 4 months ago sharing.js 3 years ago sharing.php 2 months ago
recaptcha.php
235 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Google reCAPTCHA utilities, for use in the sharing feature.
4 *
5 * @package automattic/jetpack
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit( 0 );
10 }
11
12 /**
13 * Class that handles reCAPTCHA.
14 *
15 * @deprecated 11.0
16 */
17 class Jetpack_ReCaptcha {
18
19 /**
20 * URL to which requests are POSTed.
21 *
22 * @const string
23 */
24 const VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify';
25
26 /**
27 * Site key to use in HTML code.
28 *
29 * @var string
30 */
31 private $site_key;
32
33 /**
34 * Shared secret for the site.
35 *
36 * @var string
37 */
38 private $secret_key;
39
40 /**
41 * Config for reCAPTCHA instance.
42 *
43 * @var array
44 */
45 private $config;
46
47 /**
48 * Error codes returned from reCAPTCHA API.
49 *
50 * @see https://developers.google.com/recaptcha/docs/verify
51 *
52 * @var array
53 */
54 private $error_codes;
55
56 /**
57 * Create a configured instance to use the reCAPTCHA service.
58 *
59 * @param string $site_key Site key to use in HTML code.
60 * @param string $secret_key Shared secret between site and reCAPTCHA server.
61 * @param array $config Config array to optionally configure reCAPTCHA instance.
62 */
63 public function __construct( $site_key, $secret_key, $config = array() ) {
64 $this->site_key = $site_key;
65 $this->secret_key = $secret_key;
66 $this->config = wp_parse_args( $config, $this->get_default_config() );
67
68 $this->error_codes = array(
69 'missing-input-secret' => __( 'The secret parameter is missing', 'jetpack' ),
70 'invalid-input-secret' => __( 'The secret parameter is invalid or malformed', 'jetpack' ),
71 'missing-input-response' => __( 'The response parameter is missing', 'jetpack' ),
72 'invalid-input-response' => __( 'The response parameter is invalid or malformed', 'jetpack' ),
73 'invalid-json' => __( 'Invalid JSON', 'jetpack' ),
74 'unexpected-response' => __( 'Unexpected response', 'jetpack' ),
75 'unexpected-hostname' => __( 'Unexpected hostname', 'jetpack' ),
76 );
77 }
78
79 /**
80 * Get default config for this reCAPTCHA instance.
81 *
82 * @return array Default config
83 */
84 public function get_default_config() {
85 return array(
86 'language' => get_locale(),
87 'script_async' => false,
88 'script_defer' => true,
89 'script_lazy' => false,
90 'tag_class' => 'g-recaptcha',
91 'tag_attributes' => array(
92 'theme' => 'light',
93 'type' => 'image',
94 'tabindex' => 0,
95 ),
96 );
97 }
98
99 /**
100 * Calls the reCAPTCHA siteverify API to verify whether the user passes
101 * CAPTCHA test.
102 *
103 * @param string $response The value of 'g-recaptcha-response' in the submitted
104 * form.
105 * @param string $remote_ip The end user's IP address.
106 *
107 * @return bool|WP_Error Returns true if verified. Otherwise WP_Error is returned.
108 */
109 public function verify( $response, $remote_ip ) {
110 // No need make a request if response is empty.
111 if ( empty( $response ) ) {
112 return new WP_Error( 'missing-input-response', $this->error_codes['missing-input-response'], 400 );
113 }
114
115 $resp = wp_remote_post( self::VERIFY_URL, $this->get_verify_request_params( $response, $remote_ip ) );
116 if ( is_wp_error( $resp ) ) {
117 return $resp;
118 }
119
120 $resp_decoded = json_decode( wp_remote_retrieve_body( $resp ), true );
121 if ( ! $resp_decoded ) {
122 return new WP_Error( 'invalid-json', $this->error_codes['invalid-json'], 400 );
123 }
124
125 // Default error code and message.
126 $error_code = 'unexpected-response';
127 $error_message = $this->error_codes['unexpected-response'];
128
129 // Use the first error code if exists.
130 if ( isset( $resp_decoded['error-codes'] ) && is_array( $resp_decoded['error-codes'] ) ) {
131 if ( isset( $resp_decoded['error-codes'][0] ) && isset( $this->error_codes[ $resp_decoded['error-codes'][0] ] ) ) {
132 $error_message = $this->error_codes[ $resp_decoded['error-codes'][0] ];
133 $error_code = $resp_decoded['error-codes'][0];
134 }
135 }
136
137 if ( ! isset( $resp_decoded['success'] ) ) {
138 return new WP_Error( $error_code, $error_message );
139 }
140
141 if ( true !== $resp_decoded['success'] ) {
142 return new WP_Error( $error_code, $error_message );
143 }
144 // Validate the hostname matches expected source
145 if ( isset( $resp_decoded['hostname'] ) ) {
146 $url = wp_parse_url( get_home_url() );
147
148 /**
149 * Allow other valid hostnames.
150 *
151 * This can be useful in cases where the token hostname is expected to be
152 * different from the get_home_url (ex. AMP recaptcha token contains a different hostname)
153 *
154 * @module sharedaddy
155 *
156 * @since 9.1.0
157 *
158 * @param array [ $url['host'] ] List of the valid hostnames to check against.
159 */
160 $valid_hostnames = apply_filters( 'jetpack_recaptcha_valid_hostnames', array( $url['host'] ) );
161
162 if ( ! in_array( $resp_decoded['hostname'], $valid_hostnames, true ) ) {
163 return new WP_Error( 'unexpected-host', $this->error_codes['unexpected-hostname'] );
164 }
165 }
166
167 return true;
168 }
169
170 /**
171 * Get siteverify request parameters.
172 *
173 * @param string $response The value of 'g-recaptcha-response' in the submitted
174 * form.
175 * @param string $remote_ip The end user's IP address.
176 *
177 * @return array
178 */
179 public function get_verify_request_params( $response, $remote_ip ) {
180 return array(
181 'body' => array(
182 'secret' => $this->secret_key,
183 'response' => $response,
184 'remoteip' => $remote_ip,
185 ),
186 'sslverify' => true,
187 );
188 }
189
190 /**
191 * Get reCAPTCHA HTML to render.
192 *
193 * @return string
194 */
195 public function get_recaptcha_html() {
196 $url = sprintf(
197 'https://www.google.com/recaptcha/api.js?hl=%s',
198 rawurlencode( $this->config['language'] )
199 );
200
201 $html = sprintf(
202 '
203 <div
204 class="%s"
205 data-sitekey="%s"
206 data-theme="%s"
207 data-type="%s"
208 data-tabindex="%s"
209 data-lazy="%s"
210 data-url="%s"></div>
211 ',
212 esc_attr( $this->config['tag_class'] ),
213 esc_attr( $this->site_key ),
214 esc_attr( $this->config['tag_attributes']['theme'] ),
215 esc_attr( $this->config['tag_attributes']['type'] ),
216 esc_attr( $this->config['tag_attributes']['tabindex'] ),
217 $this->config['script_lazy'] ? 'true' : 'false',
218 esc_attr( $url )
219 );
220
221 if ( ! $this->config['script_lazy'] ) {
222 $html .= sprintf(
223 // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
224 '<script src="%s"%s%s></script>
225 ',
226 $url,
227 $this->config['script_async'] && ! $this->config['script_defer'] ? ' async' : '',
228 $this->config['script_defer'] ? ' defer' : ''
229 );
230 }
231
232 return $html;
233 }
234 }
235