PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 3.0.1
Defender Security – Malware Scanner, Login Security & Firewall v3.0.1
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / src / component / mask-login.php

mask-login.php in Defender Security – Malware Scanner, Login Security & Firewall 3.0.1, at src/component/mask-login.php

197 lines 4.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WP_Defender\Component;
4
5 use WP_Defender\Component;
6
7 /**
8 * Doing the logic for mask login module.
9 *
10 * Class Mask_Login
11 *
12 * @package WP_Defender\Component
13 */
14 class Mask_Login extends Component {
15
16 /**
17 * Check if the current user is land on login page, then we can start the block.
18 * @param string $requested_path
19 *
20 * @return bool
21 */
22 public function is_on_login_page( $requested_path ) {
23 // Decoded url path, e.g. for case 'wp-%61dmin'.
24 $requested_path = rawurldecode( strtolower( $requested_path ) );
25 $login_slugs = apply_filters(
26 'wd_login_strict_slugs',
27 array(
28 'wp-admin',
29 'wp-login',
30 'wp-login.php',
31 )
32 );
33 foreach ( $login_slugs as $slug ) {
34 if ( false !== stristr( $requested_path, "$slug" ) ) {
35 return true;
36 }
37 }
38 $login_slugs = apply_filters(
39 'wd_login_slugs',
40 array(
41 'login',
42 'dashboard',
43 'admin',
44 // Because WP redirects from 'login/' to the login page.
45 'login/',
46 )
47 );
48
49 // Check the request path contains default login text.
50 if ( in_array( $requested_path, $login_slugs, true ) ) {
51 return true;
52 }
53
54 return false;
55 }
56
57 /**
58 * Check if the request is land on masked URL.
59 *
60 * @param $masked_url string
61 *
62 * @return boolean
63 */
64 public function is_land_on_masked_url( $masked_url ) {
65 return ltrim( rtrim( $this->get_request_path(), '/' ), '/' ) === ltrim( rtrim( $masked_url, '/' ), '/' );
66 }
67
68 /**
69 * Get the current request URI.
70 *
71 * @param null|string $site_url This only need in unit test.
72 *
73 * @return string
74 */
75 public function get_request_path( $site_url = null ) {
76 if ( null === $site_url ) {
77 $site_url = $this->get_site_url();
78 }
79 $request_uri = $_SERVER['REQUEST_URI'];
80 // If parsed URL is null. PHP v8.1 displays it as deprecated.
81 $path = empty( wp_parse_url( $site_url, PHP_URL_PATH ) )
82 ? ''
83 : wp_parse_url( $site_url, PHP_URL_PATH );
84 if ( strlen( $path ) && 0 === strpos( $request_uri, $path ) ) {
85 $request_uri = substr( $request_uri, strlen( $path ) );
86 }
87 $request_uri = '/' . ltrim( $request_uri, '/' );
88
89 return wp_parse_url( $request_uri, PHP_URL_PATH );
90 }
91
92 /**
93 * Copy cat from the function get_site_url without the filter.
94 *
95 * @param null $blog_id
96 * @param string $path
97 * @param null $scheme
98 *
99 * @return mixed|void
100 */
101 private function get_site_url( $blog_id = null, $path = '', $scheme = null ) {
102 if ( empty( $blog_id ) || ! is_multisite() ) {
103 $url = get_option( 'siteurl' );
104 } else {
105 switch_to_blog( $blog_id );
106 $url = get_option( 'siteurl' );
107 restore_current_blog();
108 }
109
110 $url = set_url_scheme( $url, $scheme );
111
112 if ( $path && is_string( $path ) ) {
113 $url .= '/' . ltrim( $path, '/' );
114 }
115
116 return $url;
117 }
118
119 /**
120 * Generate a random unique onetime pass and store in user meta.
121 * Later we can use it to bypass the mask admin.
122 *
123 * @return bool
124 */
125 public function generate_ticket() {
126 $otp = wp_generate_password( 12, false );
127 $settings = new \WP_Defender\Model\Setting\Mask_Login();
128 $settings->express_tickets[ $otp ] = array(
129 'otp' => $otp,
130 'bind_to' => null,
131 'expiry' => strtotime( '+3 day' ),
132 'used' => 0,
133 );
134 $settings->save();
135
136 return $otp;
137 }
138
139 /**
140 * Todo: need if express_tickets are not saved?
141 * @param string $url
142 *
143 * @return string
144 */
145 public function maybe_append_ticket_to_url( $url ) {
146 return add_query_arg( 'ticket', $this->generate_ticket(), $url );
147 }
148
149 /**
150 * Todo: need if express_tickets are not saved?
151 * @param string $ticket
152 *
153 * @return bool
154 */
155 public function redeem_ticket( $ticket ) {
156 $settings = new \WP_Defender\Model\Setting\Mask_Login();
157 $detail = $settings->express_tickets[ $ticket ] ?? false;
158 if ( false === $detail ) {
159 return false;
160 }
161
162 // Ticket expired.
163 if ( $detail['expiry'] < time() ) {
164 unset( $settings->express_tickets[ $ticket ] );
165 $settings->save();
166
167 return false;
168 }
169
170 $detail['used'] += 1;
171 $settings->express_tickets[ $ticket ] = $detail;
172 $settings->save();
173
174 return true;
175 }
176
177 /**
178 * Check if the HTTP_USER_AGENT is a bot.
179 *
180 * @return bool
181 */
182 public function is_bot_request() {
183 if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
184 return false;
185 }
186
187 if ( preg_match(
188 '/bot|crawl|curl|dataprovider|search|get|spider|find|java|majesticsEO|google|yahoo|teoma|contaxe|yandex|libwww-perl|facebookexternalhit/i',
189 $_SERVER['HTTP_USER_AGENT']
190 ) ) {
191 return true;
192 } else {
193 return false;
194 }
195 }
196 }
197