PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 10.1.1
Jetpack – WP Security, Backup, Speed, & Growth v10.1.1
12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 All 500 releases
jetpack / modules / protect / math-fallback.php
math-fallback.php
165 lines 6.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! class_exists( 'Jetpack_Protect_Math_Authenticate' ) ) {
4 /*
5 * The math captcha fallback if we can't talk to the Protect API
6 */
7 class Jetpack_Protect_Math_Authenticate {
8
9 static $loaded;
10
11 function __construct() {
12
13 if ( self::$loaded ) {
14 return;
15 }
16
17 self::$loaded = 1;
18
19 add_action( 'login_form', array( $this, 'math_form' ) );
20
21 if( isset( $_POST[ 'jetpack_protect_process_math_form' ] ) ) {
22 add_action( 'init', array( $this, 'process_generate_math_page' ) );
23 }
24 }
25
26 private static function time_window() {
27 return ceil( time() / ( MINUTE_IN_SECONDS * 2 ) );
28 }
29
30 /**
31 * Verifies that a user answered the math problem correctly while logging in.
32 *
33 * @return bool Returns true if the math is correct
34 * @throws Error if insuffient $_POST variables are present.
35 * @throws Error message if the math is wrong
36 */
37 static function math_authenticate() {
38 if( isset( $_COOKIE[ 'jpp_math_pass' ] ) ) {
39 $jetpack_protect = Jetpack_Protect_Module::instance();
40 $transient = $jetpack_protect->get_transient( 'jpp_math_pass_' . $_COOKIE[ 'jpp_math_pass' ] );
41
42 if( !$transient || $transient < 1 ) {
43 Jetpack_Protect_Math_Authenticate::generate_math_page();
44 }
45 return true;
46 }
47
48 $ans = isset( $_POST['jetpack_protect_num'] ) ? (int) $_POST['jetpack_protect_num'] : '' ;
49 $correct_ans = isset( $_POST[ 'jetpack_protect_answer' ] ) ? $_POST[ 'jetpack_protect_answer' ] : '' ;
50
51 $time_window = Jetpack_Protect_Math_Authenticate::time_window();
52 $salt = get_site_option( 'jetpack_protect_key' ) . '|' . get_site_option( 'admin_email' ) . '|';
53 $salted_ans_1 = hash_hmac( 'sha1', $ans, $salt . $time_window );
54 $salted_ans_2 = hash_hmac( 'sha1', $ans, $salt . ( $time_window - 1 ) );
55
56 if ( ! $correct_ans || ! $ans ) {
57 Jetpack_Protect_Math_Authenticate::generate_math_page();
58 } elseif ( ! hash_equals( $salted_ans_1, $correct_ans ) && ! hash_equals( $salted_ans_2, $correct_ans ) ) {
59 wp_die(
60 wp_kses(
61 __(
62 '<strong>You failed to correctly answer the math problem.</strong> This is used to combat spam when the Protect API is unavailable. Please use your browser’s back button to return to the login form, press the "refresh" button to generate a new math problem, and try to log in again.',
63 'jetpack'
64 ),
65 array( 'strong' => array() )
66 ),
67 '',
68 array( 'response' => 401 )
69 );
70 } else {
71 return true;
72 }
73 }
74
75 /**
76 * Creates an interim page to collect answers to a math captcha
77 *
78 * @return none, execution stopped
79 */
80 static function generate_math_page( $error = false ) {
81 ob_start();
82 ?>
83 <h2><?php esc_html_e( 'Please solve this math problem to prove that you are not a bot. Once you solve it, you will need to log in again.', 'jetpack' ); ?></h2>
84 <?php if ($error): ?>
85 <h3><?php esc_html_e( 'Your answer was incorrect, please try again.', 'jetpack' ); ?></h3>
86 <?php endif ?>
87
88 <form action="<?php echo wp_login_url(); ?>" method="post" accept-charset="utf-8">
89 <?php Jetpack_Protect_Math_Authenticate::math_form(); ?>
90 <input type="hidden" name="jetpack_protect_process_math_form" value="1" id="jetpack_protect_process_math_form" />
91 <p><input type="submit" value="<?php esc_attr_e( 'Continue &rarr;', 'jetpack' ); ?>"></p>
92 </form>
93 <?php
94 $mathpage = ob_get_contents();
95 ob_end_clean();
96 wp_die(
97 $mathpage,
98 '',
99 array ( 'response' => 401 )
100 );
101 }
102
103 public function process_generate_math_page() {
104 $ans = isset( $_POST['jetpack_protect_num'] ) ? (int)$_POST['jetpack_protect_num'] : '';
105 $correct_ans = isset( $_POST[ 'jetpack_protect_answer' ] ) ? $_POST[ 'jetpack_protect_answer' ] : '' ;
106
107 $time_window = Jetpack_Protect_Math_Authenticate::time_window();
108 $salt = get_site_option( 'jetpack_protect_key' ) . '|' . get_site_option( 'admin_email' ) . '|';
109 $salted_ans_1 = hash_hmac( 'sha1', $ans, $salt . $time_window );
110 $salted_ans_2 = hash_hmac( 'sha1', $ans, $salt . ( $time_window - 1 ) );
111
112 if ( ! hash_equals( $salted_ans_1, $correct_ans ) && ! hash_equals( $salted_ans_2, $correct_ans ) ) {
113 Jetpack_Protect_Math_Authenticate::generate_math_page(true);
114 } else {
115 $temp_pass = substr( hash_hmac( 'sha1', rand( 1, 100000000 ), get_site_option( 'jetpack_protect_key' ) ), 5, 25 );
116
117 $jetpack_protect = Jetpack_Protect_Module::instance();
118 $jetpack_protect->set_transient( 'jpp_math_pass_' . $temp_pass, 3, DAY_IN_SECONDS );
119 setcookie('jpp_math_pass', $temp_pass, time() + DAY_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN, false);
120 remove_action( 'login_form', array( $this, 'math_form' ) );
121 return true;
122 }
123 }
124
125 /**
126 * Requires a user to solve a simple equation. Added to any WordPress login form.
127 *
128 * @return VOID outputs html
129 */
130 static function math_form() {
131 // Check if jpp_math_pass cookie is set and it matches valid transient
132 if( isset( $_COOKIE[ 'jpp_math_pass' ] ) ) {
133 $jetpack_protect = Jetpack_Protect_Module::instance();
134 $transient = $jetpack_protect->get_transient( 'jpp_math_pass_' . $_COOKIE[ 'jpp_math_pass' ] );
135
136 if( $transient && $transient > 0 ) {
137 return '';
138 }
139 }
140
141 $num1 = rand( 0, 10 );
142 $num2 = rand( 1, 10 );
143 $ans = $num1 + $num2;
144
145 $time_window = Jetpack_Protect_Math_Authenticate::time_window();
146 $salt = get_site_option( 'jetpack_protect_key' ) . '|' . get_site_option( 'admin_email' ) . '|';
147 $salted_ans = hash_hmac( 'sha1', $ans, $salt . $time_window );
148 ?>
149 <div style="margin: 5px 0 20px;">
150 <label for="jetpack_protect_answer">
151 <?php esc_html_e( 'Prove your humanity', 'jetpack' ); ?>
152 </label>
153 <br/>
154 <span style="vertical-align:super;">
155 <?php echo esc_html( "$num1 &nbsp; + &nbsp; $num2 &nbsp; = &nbsp;" ); ?>
156 </span>
157 <input type="text" id="jetpack_protect_answer" name="jetpack_protect_num" value="" size="2" style="width:30px;height:25px;vertical-align:middle;font-size:13px;" class="input" />
158 <input type="hidden" name="jetpack_protect_answer" value="<?php echo esc_attr( $salted_ans ); ?>" />
159 </div>
160 <?php
161 }
162
163 }
164 }
165