PluginProbe ʕ •ᴥ•ʔ
CloudSecure WP Security / 1.1.1
CloudSecure WP Security v1.1.1
1.4.10 1.4.9 trunk 0.9.0 1.0.2 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 1.3.17 1.3.18 1.3.19 1.3.2 1.3.20 1.3.21 1.3.22 1.3.23 1.3.24 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8
cloudsecure-wp-security / modules / captcha.php
cloudsecure-wp-security / modules Last commit date
admin 2 years ago lib 2 years ago captcha.php 2 years ago cloudsecure-wp.php 2 years ago common.php 2 years ago config.php 2 years ago disable-author-query.php 2 years ago disable-login.php 2 years ago disable-restapi.php 2 years ago disable-xmlrpc.php 2 years ago htaccess.php 2 years ago login-log.php 2 years ago login-notification.php 2 years ago rename-login-page.php 2 years ago restrict-admin-page.php 2 years ago server-error-notification.php 2 years ago two-factor-authentication.php 2 years ago unify-messages.php 2 years ago update-notice.php 2 years ago
captcha.php
369 lines
1 <?php
2
3 class CloudSecureWP_CAPTCHA extends CloudSecureWP_Common {
4 private const KEY_FEATURE = 'captcha';
5 private const KEY_LOGIN = self::KEY_FEATURE . '_login';
6 private const KEY_COMMENT = self::KEY_FEATURE . '_comment';
7 private const KEY_LOST_PASSWORD = self::KEY_FEATURE . '_lost_password';
8 private const KEY_REGISTER = self::KEY_FEATURE . '_register';
9 private const LOGIN_VALUES = array( 1, 2 ); // 無効, 有効 .
10 private const COMMENT_VALUES = array( 1, 2 ); // 無効, 有効 .
11 private const LOST_PASSWORD_VALUES = array( 1, 2 ); // 無効, 有効 .
12 private const REGISTER_VALUES = array( 1, 2 ); // 無効, 有効 .
13 private const ERROR_CODE = 'cloudsecurewp_captcha_error';
14 private const CAPTCHA_FORM_NAME = 'cloudsecurewp_captcha';
15 private const PREFIX_FORM_NAME = 'cloudsecurewp_captcha_prefix';
16 private const CAPTCHA_ERROR_MESSAGE = 'エラー:画像認証に失敗しました';
17
18 private $config;
19 private $captcha;
20 private $allowed_html;
21
22 function __construct( array $info, CloudSecureWP_Config $config ) {
23 parent::__construct( $info );
24 $this->config = $config;
25 $this->captcha = new CloudSecureWP_ReallySimpleCaptcha();
26 $this->allowed_html = array(
27 'p' => array(
28 'class' => array(),
29 ),
30 'style' => array(),
31 'label' => array(
32 'for' => array(),
33 ),
34 'img' => array(
35 'src' => array(),
36 'alt' => array(),
37 ),
38 'input' => array(
39 'type' => array(),
40 'id' => array(),
41 'name' => array(),
42 'class' => array(),
43 'value' => array(),
44 'size' => array(),
45 'aria-required' => array(),
46 ),
47 );
48 }
49
50 /**
51 * 機能毎のKEY取得
52 *
53 * @return string
54 */
55 public function get_feature_key(): string {
56 return self::KEY_FEATURE;
57 }
58
59 /**
60 * 有効無効判定
61 *
62 * @return bool
63 */
64 public function is_enabled(): bool {
65 return $this->config->get( $this->get_feature_key() ) === 't' ? true : false;
66 }
67
68 /**
69 * ログインフォームの有効無効判定
70 */
71 public function is_login_form_enabled(): bool {
72 return ( (int) $this->config->get( self::KEY_LOGIN ) === (int) self::LOGIN_VALUES[1] ) ? true : false;
73 }
74
75 /**
76 * コメントフォームの有効無効判定
77 */
78 public function is_comment_form_enabled(): bool {
79 return ( (int) $this->config->get( self::KEY_COMMENT ) === (int) self::COMMENT_VALUES[1] ) ? true : false;
80 }
81
82 /**
83 * パスワードリセットフォームの有効無効判定
84 */
85 public function is_lost_password_form_enabled(): bool {
86 return ( (int) $this->config->get( self::KEY_LOST_PASSWORD ) === (int) self::LOST_PASSWORD_VALUES[1] ) ? true : false;
87 }
88
89 /**
90 * ユーザー登録フォームの有効無効判定
91 */
92 public function is_register_form_enabled(): bool {
93 return ( (int) $this->config->get( self::KEY_REGISTER ) === (int) self::REGISTER_VALUES[1] ) ? true : false;
94 }
95
96 /**
97 * 初期設定値取得
98 *
99 * @return array
100 */
101 public function get_default(): array {
102 return array(
103 self::KEY_FEATURE => 'f',
104 self::KEY_LOGIN => self::LOGIN_VALUES[1],
105 self::KEY_COMMENT => self::COMMENT_VALUES[1],
106 self::KEY_LOST_PASSWORD => self::LOST_PASSWORD_VALUES[1],
107 self::KEY_REGISTER => self::REGISTER_VALUES[1],
108 );
109 }
110
111 /**
112 * 設定値key取得
113 */
114 public function get_keys(): array {
115 return array(
116 self::KEY_FEATURE,
117 self::KEY_LOGIN,
118 self::KEY_COMMENT,
119 self::KEY_LOST_PASSWORD,
120 self::KEY_REGISTER,
121 );
122 }
123
124 /**
125 * 設定値取得
126 */
127 public function get_settings(): array {
128 $settings = array();
129 $keys = $this->get_keys();
130
131 foreach ( $keys as $key ) {
132 $settings[ $key ] = $this->config->get( $key );
133 }
134
135 return $settings;
136 }
137
138 /**
139 * 設定値保存
140 *
141 * @param array $settings
142 * @return void
143 */
144 public function save_settings( $settings ): void {
145 $keys = $this->get_keys();
146
147 foreach ( $keys as $key ) {
148 $this->config->set( $key, $settings[ $key ] ?? '' );
149 }
150 $this->config->save();
151 }
152
153 /**
154 * 設定定義値取得
155 *
156 * @return array
157 */
158 public function get_constant_settings(): array {
159 return array(
160 self::KEY_LOGIN => self::LOGIN_VALUES,
161 self::KEY_COMMENT => self::COMMENT_VALUES,
162 self::KEY_LOST_PASSWORD => self::LOST_PASSWORD_VALUES,
163 self::KEY_REGISTER => self::REGISTER_VALUES,
164 );
165 }
166
167 /**
168 * 動作環境チェック
169 *
170 * @return string
171 */
172 public function check_modules(): string {
173 $ret = $this->check_gd();
174 if ( '' !== $ret ) {
175 return $ret;
176 }
177
178 $ret = $this->check_captcha_save_dir();
179 if ( '' !== $ret ) {
180 return $ret;
181 }
182
183 return $ret;
184 }
185
186 /**
187 * GDライブラリチェック
188 *
189 * @return string
190 */
191 public function check_gd(): string {
192 $gd = gd_info();
193
194 if ( empty( $gd ) ) {
195 return 'GDライブラリを利用できません';
196 }
197
198 if ( ! array_key_exists( 'FreeType Support', $gd ) || false === $gd['FreeType Support'] ) {
199 return 'FreeType が無効です';
200 }
201
202 return '';
203 }
204
205 /**
206 * 画像認証画像保存確認
207 *
208 * @return string
209 */
210 public function check_captcha_save_dir(): string {
211 if ( ! $this->captcha->make_tmp_dir() ) {
212 return '画像認証画像保存ディレクトリを作成できません: ' . $this->captcha->tmp_dir;
213 }
214
215 return '';
216 }
217
218 /**
219 * 有効化
220 *
221 * @return void
222 */
223 public function activate(): void {
224 $settings = $this->get_default();
225 $this->save_settings( $settings );
226 }
227
228 /**
229 * 無効化
230 *
231 * @return void
232 */
233 public function deactivate(): void {
234 $settings = $this->get_settings();
235 $settings[ self::KEY_FEATURE ] = 'f';
236 $this->save_settings( $settings );
237 }
238
239 /**
240 * 画像認証
241 *
242 * @return string
243 */
244 function create_captcha(): string {
245 $word = $this->captcha->generate_random_word();
246 $prefix = mt_rand();
247 $this->captcha->generate_image( $prefix, $word );
248
249 $captcha = '<p class="cloudsecure-wp-captcha-block">' . "\n";
250 $captcha .= ' <style>' . "\n";
251 $captcha .= ' .cloudsecure-wp-captcha-block label{' . "\n";
252 $captcha .= ' display: block;' . "\n";
253 $captcha .= ' }' . "\n";
254 $captcha .= ' .cloudsecure-wp-captcha-block label img{' . "\n";
255 $captcha .= ' border: 1px solid #CCCCCC;' . "\n";
256 $captcha .= ' padding: 8px;' . "\n";
257 $captcha .= ' margin-top: 2px;' . "\n";
258 $captcha .= ' }' . "\n";
259 $captcha .= ' </style>' . "\n";
260 $captcha .= ' <label for="' . self::CAPTCHA_FORM_NAME . '">画像に表示された文字を�
261 �力してください</label>' . "\n";
262 $captcha .= ' <label for="' . self::CAPTCHA_FORM_NAME . '"><img src="' . $this->info['plugin_url'] . 'really-simple-captcha/tmp/' . $prefix . '.png" alt="CAPTCHA"></label>' . "\n";
263 $captcha .= ' <input type="text" id="' . self::CAPTCHA_FORM_NAME . '" name="' . self::CAPTCHA_FORM_NAME . '" class="input" value="" size="10" aria-required="true" />' . "\n";
264 $captcha .= ' <input type="hidden" id="' . self::PREFIX_FORM_NAME . '" name="' . self::PREFIX_FORM_NAME . '" value="' . $prefix . '" />' . "\n";
265 $captcha .= wp_nonce_field( $this->get_feature_key() . '_csrf', 'cloudsecurewp_captcha_wpnonce', true, false ) . "\n";
266 $captcha .= '</p>' . "\n";
267
268 return $captcha;
269 }
270
271 /**
272 * 画像認証チェック
273 *
274 * @return bool
275 */
276 public function check_captcha(): bool {
277 if ( ! empty( $_POST ) && check_admin_referer( $this->get_feature_key() . '_csrf', 'cloudsecurewp_captcha_wpnonce' ) ) {
278 return $this->captcha->check( sanitize_text_field( $_POST[ self::PREFIX_FORM_NAME ] ?? '' ), sanitize_text_field( $_POST[ self::CAPTCHA_FORM_NAME ] ?? '' ) );
279 }
280
281 return false;
282 }
283
284 /**
285 * 画像認証エラー
286 */
287 public function get_captcha_error() {
288 return new WP_Error( self::ERROR_CODE, self::CAPTCHA_ERROR_MESSAGE );
289 }
290
291 /**
292 * エラーコード追加
293 */
294 public function shake_error_codes( $error_codes ) {
295 array_push( $error_codes, self::ERROR_CODE );
296 return $error_codes;
297 }
298
299 /**
300 * ログインフォーム画像認証
301 */
302 public function login_form() {
303 echo wp_kses( $this->create_captcha(), $this->allowed_html );
304 }
305
306 /**
307 * ログインフォーム画像認証チェック
308 */
309 public function wp_authenticate_user( $user, $password ) {
310 if ( $this->check_captcha() ) {
311 return $user;
312 }
313
314 return $this->get_captcha_error();
315 }
316
317 /**
318 * コメントフォーム画像認証
319 */
320 public function comment_form_default_fields() {
321 echo wp_kses( $this->create_captcha(), $this->allowed_html );
322 }
323
324 /**
325 * コメントフォーム画像認証チェック
326 */
327 public function preprocess_comment( $comment_data ) {
328 if ( is_admin() || $this->check_captcha() ) {
329 return $comment_data;
330 }
331
332 wp_die( esc_html( self::CAPTCHA_ERROR_MESSAGE ), esc_html( 'ERROR' ), array( 'back_link' => true ) );
333 }
334
335 /**
336 * パスワードリセットフォーム画像認証
337 */
338 public function lostpassword_form() {
339 echo wp_kses( $this->create_captcha(), $this->allowed_html );
340 }
341
342 /**
343 * パスワードリセットフォーム画像認証チェック
344 */
345 public function allow_password_reset( $allow_reset, $user_id ) {
346 if ( $this->check_captcha() ) {
347 return $allow_reset;
348 }
349
350 return $this->get_captcha_error();
351 }
352
353 /**
354 * ユーザー登録フォーム画像認証
355 */
356 public function register_form() {
357 echo wp_kses( $this->create_captcha(), $this->allowed_html );
358 }
359
360 /**
361 * ユーザー登録フォーム画像認証チェック
362 */
363 public function register_post( $username, $email, $errors ) {
364 if ( ! $this->check_captcha() ) {
365 $errors->add( self::CAPTCHA_FORM_NAME, self::CAPTCHA_ERROR_MESSAGE );
366 }
367 }
368 }
369