This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * WP PHP Console |
||
4 | * |
||
5 | * This source file is subject to the GNU General Public License v3.0 |
||
6 | * that is bundled with this package in the file license.txt. |
||
7 | * It is also available through the world-wide-web at this URL: |
||
8 | * http://www.gnu.org/licenses/gpl-3.0.html |
||
9 | * |
||
10 | * @author Fulvio Notarstefano <[email protected]> |
||
11 | * @copyright Copyright (c) 2014-2020 Fulvio Notarstefano |
||
12 | * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 |
||
13 | */ |
||
14 | |||
15 | namespace WP_PHP_Console; |
||
16 | |||
17 | use PhpConsole; |
||
18 | |||
19 | defined( 'ABSPATH' ) or exit; |
||
20 | |||
21 | /** |
||
22 | * WP PHP Console main class. |
||
23 | * |
||
24 | * @since 1.0.0 |
||
25 | */ |
||
26 | class Plugin { |
||
27 | |||
28 | |||
29 | /** @var string plugin version */ |
||
30 | CONST VERSION = '1.6.0'; |
||
31 | |||
32 | /** @var string plugin ID */ |
||
33 | CONST ID = 'wp-php-console'; |
||
34 | |||
35 | /** @var string plugin name */ |
||
36 | CONST NAME = 'WP PHP Console'; |
||
37 | |||
38 | |||
39 | /** @var PhpConsole\Connector instance */ |
||
40 | public $connector; |
||
41 | |||
42 | |||
43 | /** |
||
44 | * Loads plugin and connects to PHP Console. |
||
45 | * |
||
46 | * @since 1.0.0 |
||
47 | */ |
||
48 | public function __construct() { |
||
49 | |||
50 | @error_reporting( E_ALL ); |
||
0 ignored issues
–
show
|
|||
51 | |||
52 | foreach ( [ 'WP_DEBUG', 'WP_DEBUG_LOG', 'WP_DEBUG_DISPLAY', ] as $wp_debug_constant ) { |
||
53 | if ( ! defined( $wp_debug_constant ) ) { |
||
54 | define ( $wp_debug_constant, true ); |
||
55 | } |
||
56 | } |
||
57 | |||
58 | // handle translations |
||
59 | add_action( 'plugins_loaded', static function() { |
||
60 | load_plugin_textdomain( |
||
61 | 'wp-php-console', |
||
62 | false, |
||
63 | dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/' |
||
64 | ); |
||
65 | } ); |
||
66 | |||
67 | if ( class_exists( 'PhpConsole\Connector' ) ) { |
||
68 | // connect to PHP Console |
||
69 | add_action( 'init', [ $this, 'connect' ], -1000 ); |
||
70 | // delay further PHP Console initialisation to have more context during Remote PHP execution |
||
71 | add_action( 'wp_loaded', [ $this, 'init' ], -1000 ); |
||
72 | } |
||
73 | |||
74 | // load admin |
||
75 | if ( is_admin() ) { |
||
76 | new Admin(); |
||
77 | } |
||
78 | } |
||
79 | |||
80 | |||
81 | /** |
||
82 | * Connects to PHP Console. |
||
83 | * |
||
84 | * PHP Console needs to hook in session, in WordPress we need to be in 'init': |
||
85 | * @link http://silvermapleweb.com/using-the-php-session-in-wordpress/ |
||
86 | * |
||
87 | * @internal action hook callback |
||
88 | * |
||
89 | * @since 1.4.0 |
||
90 | */ |
||
91 | public function connect() { |
||
92 | |||
93 | // workaround for avoiding headers already sent warnings |
||
94 | @error_reporting( E_ALL & ~E_WARNING ); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
95 | |||
96 | if ( ! @session_id() ) { |
||
97 | @session_start(); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
98 | } |
||
99 | |||
100 | $connected = true; |
||
101 | |||
102 | if ( ! $this->connector instanceof PhpConsole\Connector ) { |
||
103 | try { |
||
104 | $this->connector = PhpConsole\Connector::getInstance(); |
||
105 | } catch ( \Exception $e ) { |
||
106 | $connected = false; |
||
107 | } |
||
108 | } |
||
109 | |||
110 | // restore error reporting |
||
111 | @error_reporting( E_ALL ); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
112 | |||
113 | // apply PHP Console options |
||
114 | if ( $connected ) { |
||
115 | $this->apply_options(); |
||
116 | } |
||
117 | } |
||
118 | |||
119 | |||
120 | /** |
||
121 | * Applies options. |
||
122 | * |
||
123 | * @since 1.4.0 |
||
124 | */ |
||
125 | private function apply_options() { |
||
126 | |||
127 | // bail out if not connected yet to PHP Console |
||
128 | if ( ! $this->connector instanceof PhpConsole\Connector ) { |
||
129 | return; |
||
130 | } |
||
131 | |||
132 | // apply 'register' option to PHP Console... |
||
133 | if ( Settings::should_register_pc_class() && ! class_exists( 'PC', false ) ) { |
||
134 | // ...only if PC not registered yet |
||
135 | try { |
||
136 | PhpConsole\Helper::register(); |
||
137 | } catch( \Exception $e ) { |
||
138 | $this->print_notice_exception( $e ); |
||
139 | } |
||
140 | } |
||
141 | |||
142 | // apply 'stack' option to PHP Console |
||
143 | if ( Settings::should_show_call_stack() ) { |
||
144 | $this->connector->getDebugDispatcher()->detectTraceAndSource = true; |
||
145 | } |
||
146 | |||
147 | // apply 'short' option to PHP Console |
||
148 | if ( Settings::should_use_short_path_names() ) { |
||
149 | try { |
||
150 | $this->connector->setSourcesBasePath( $_SERVER['DOCUMENT_ROOT'] ); |
||
151 | } catch ( \Exception $e ) { |
||
152 | $this->print_notice_exception( $e ); |
||
153 | } |
||
154 | } |
||
155 | } |
||
156 | |||
157 | |||
158 | /** |
||
159 | * Initializes PHP Console. |
||
160 | * |
||
161 | * @internal action hook callback |
||
162 | * |
||
163 | * @since 1.0.0 |
||
164 | */ |
||
165 | public function init() { |
||
166 | |||
167 | // bail if no password is set to connect with PHP Console |
||
168 | if ( ! Settings::has_eval_terminal_password() ) { |
||
169 | return; |
||
170 | } |
||
171 | |||
172 | // selectively remove slashes added by WordPress as expected by PHP Console |
||
173 | if ( array_key_exists( PhpConsole\Connector::POST_VAR_NAME, $_POST ) ) { |
||
174 | $_POST[ PhpConsole\Connector::POST_VAR_NAME ] = stripslashes_deep( $_POST[ PhpConsole\Connector::POST_VAR_NAME ] ); |
||
175 | } |
||
176 | |||
177 | // get PHP Console instance if wasn't set yet |
||
178 | if ( ! $this->connector instanceof PhpConsole\Connector ) { |
||
179 | |||
180 | // workaround for avoiding headers already sent warnings |
||
181 | @error_reporting( E_ALL & ~E_WARNING ); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
182 | |||
183 | try { |
||
184 | $this->connector = PhpConsole\Connector::getInstance(); |
||
185 | $connected = true; |
||
186 | } catch ( \Exception $e ) { |
||
187 | $connected = false; |
||
188 | } |
||
189 | |||
190 | // restore error reporting |
||
191 | @error_reporting( E_ALL ); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
192 | |||
193 | if ( ! $connected ) { |
||
194 | return; |
||
195 | } |
||
196 | } |
||
197 | |||
198 | // set PHP Console password |
||
199 | try { |
||
200 | $this->connector->setPassword( Settings::get_eval_terminal_password() ); |
||
201 | } catch ( \Exception $e ) { |
||
202 | $this->print_notice_exception( $e ); |
||
203 | } |
||
204 | |||
205 | // get PHP Console handler instance |
||
206 | $handler = PhpConsole\Handler::getInstance(); |
||
207 | |||
208 | if ( true !== PhpConsole\Handler::getInstance()->isStarted() ) { |
||
209 | try { |
||
210 | $handler->start(); |
||
211 | } catch( \Exception $e ) { |
||
212 | $this->print_notice_exception( $e ); |
||
213 | return; |
||
214 | } |
||
215 | } |
||
216 | |||
217 | // enable SSL-only mode |
||
218 | if ( Settings::should_use_ssl_only() ) { |
||
219 | $this->connector->enableSslOnlyMode(); |
||
220 | } |
||
221 | |||
222 | // restrict IP addresses |
||
223 | $allowedIpMasks = Settings::get_allowed_ip_masks(); |
||
224 | |||
225 | if ( count( $allowedIpMasks ) > 0 ) { |
||
226 | $this->connector->setAllowedIpMasks( $allowedIpMasks ); |
||
227 | } |
||
228 | |||
229 | $evalProvider = $this->connector->getEvalDispatcher()->getEvalProvider(); |
||
230 | |||
231 | try { |
||
232 | $evalProvider->addSharedVar( 'uri', $_SERVER['REQUEST_URI'] ); |
||
233 | } catch ( \Exception $e ) { |
||
234 | $this->print_notice_exception( $e ); |
||
235 | } |
||
236 | |||
237 | try { |
||
238 | $evalProvider->addSharedVarReference( 'post', $_POST ); |
||
239 | } catch ( \Exception $e ) { |
||
240 | $this->print_notice_exception( $e ); |
||
241 | } |
||
242 | |||
243 | $openBaseDirs = [ ABSPATH, get_template_directory() ]; |
||
244 | |||
245 | try { |
||
246 | $evalProvider->addSharedVarReference( 'dirs', $openBaseDirs ); |
||
247 | } catch ( \Exception $e ) { |
||
248 | $this->print_notice_exception( $e ); |
||
249 | } |
||
250 | |||
251 | $evalProvider->setOpenBaseDirs( $openBaseDirs ); |
||
252 | |||
253 | try { |
||
254 | $this->connector->startEvalRequestsListener(); |
||
255 | } catch ( \Exception $e ) { |
||
256 | $this->print_notice_exception( $e ); |
||
257 | } |
||
258 | } |
||
259 | |||
260 | |||
261 | /** |
||
262 | * Prints an exception message as WordPress admin notice. |
||
263 | * |
||
264 | * @since 1.4.0 |
||
265 | * |
||
266 | * @param \Exception $e Exception object |
||
267 | */ |
||
268 | private function print_notice_exception( \Exception $e ) { |
||
269 | |||
270 | add_action( 'admin_notices', static function() use ( $e ) { |
||
271 | ?> |
||
272 | <div class="error"> |
||
273 | <p><?php printf( '%1$s: %2$s', self::NAME, $e->getMessage() ); ?></p> |
||
274 | </div> |
||
275 | <?php |
||
276 | } ); |
||
277 | } |
||
278 | |||
279 | |||
280 | /** |
||
281 | * Gets the plugin path. |
||
282 | * |
||
283 | * @since 1.6.0 |
||
284 | * |
||
285 | * @return string |
||
286 | */ |
||
287 | public static function get_plugin_path() { |
||
288 | |||
289 | return untrailingslashit( dirname( __DIR__ ) ); |
||
290 | } |
||
291 | |||
292 | |||
293 | /** |
||
294 | * Gets the plugin vendor path. |
||
295 | * |
||
296 | * @since 1.6.0 |
||
297 | */ |
||
298 | public static function get_plugin_vendor_path() { |
||
299 | |||
300 | return self::get_plugin_path() . '/vendor'; |
||
301 | } |
||
302 | |||
303 | |||
304 | /** |
||
305 | * Gets the plugin page URL. |
||
306 | * |
||
307 | * @since 1.6.0 |
||
308 | * |
||
309 | * @return string |
||
310 | */ |
||
311 | public static function get_plugin_page_url() { |
||
312 | |||
313 | return 'https://wordpress.org/support/plugin/wp-php-console/'; |
||
314 | } |
||
315 | |||
316 | |||
317 | /** |
||
318 | * Gets the plugin reviews page URL. |
||
319 | * |
||
320 | * @since 1.6.0 |
||
321 | * |
||
322 | * @return string |
||
323 | */ |
||
324 | public static function get_reviews_page_url() { |
||
325 | |||
326 | return 'https://wordpress.org/support/plugin/wp-php-console/reviews/'; |
||
327 | } |
||
328 | |||
329 | |||
330 | /** |
||
331 | * Gets the plugin support page URL. |
||
332 | * |
||
333 | * @since 1.6.0 |
||
334 | * |
||
335 | * @return string |
||
336 | */ |
||
337 | public static function get_support_page_url() { |
||
338 | |||
339 | return 'https://wordpress.org/support/plugin/wp-php-console/'; |
||
340 | } |
||
341 | |||
342 | |||
343 | /** |
||
344 | * Gets the GitHub repository page URL. |
||
345 | * |
||
346 | * @since 1.6.0 |
||
347 | * |
||
348 | * @return string |
||
349 | */ |
||
350 | public static function get_wp_php_console_repository_url() { |
||
351 | |||
352 | return 'https://github.com/unfulvio/wp-php-console'; |
||
353 | } |
||
354 | |||
355 | |||
356 | /** |
||
357 | * Gets the PHP Console project page URL. |
||
358 | * |
||
359 | * @since 1.6.0 |
||
360 | * |
||
361 | * @return string |
||
362 | */ |
||
363 | public static function get_php_console_repository_url() { |
||
364 | |||
365 | return 'https://github.com/barbushin/php-console'; |
||
366 | } |
||
367 | |||
368 | |||
369 | /** |
||
370 | * Gets the PHP Console Google Chrome extension URL. |
||
371 | * |
||
372 | * @since 1.6.0 |
||
373 | * |
||
374 | * @return string |
||
375 | */ |
||
376 | public static function get_php_console_chrome_extension_web_store_url() { |
||
377 | |||
378 | return 'https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef'; |
||
379 | } |
||
380 | |||
381 | |||
382 | /** |
||
383 | * Gets the PHP Console Google Chrome extension repository URL. |
||
384 | * |
||
385 | * @since 1.6.0 |
||
386 | * |
||
387 | * @return string |
||
388 | */ |
||
389 | public static function get_php_console_chrome_extension_repository_url() { |
||
390 | |||
391 | return 'https://github.com/barbushin/php-console-extension'; |
||
392 | } |
||
393 | |||
394 | |||
395 | } |
||
396 |
If you suppress an error, we recommend checking for the error condition explicitly: