44 * Description: Speeds up Plausible Analytics' proxy for avoiding ad blockers.
55 * Plugin URI: https://plausible.io
66 * Author: Plausible HQ
7- * Version: 1.0.0
7+ * Version: 1.0.1
88 * Author URI: https://plausible.io
99 *
1010 * Text Domain: plausible-analytics
1111 */
1212
1313class PlausibleProxySpeed {
1414 /**
15- * Is current request a request to our proxy?
15+ * Is the current request a request to our proxy?
1616 *
1717 * @var bool
1818 */
19- private $ is_proxy_request = false ;
19+ private $ is_proxy_request ;
2020
2121 /**
2222 * Current request URI.
2323 *
2424 * @var string
2525 */
26- private $ request_uri = '' ;
26+ private $ request_uri ;
2727
2828 /**
2929 * Build properties.
@@ -38,27 +38,44 @@ public function __construct() {
3838 }
3939
4040 /**
41- * Helper method to retrieve Request URI. Checks several globals.
41+ * Helper method to retrieve Request URI.
4242 *
43- * @return mixed
43+ * @return string
4444 */
4545 private function get_request_uri () {
46- return $ _SERVER [ 'REQUEST_URI ' ] ;
46+ return $ _SERVER ['REQUEST_URI ' ] ?? '' ;
4747 }
4848
4949 /**
50- * Check if current request is a proxy request.
50+ * Check if the current request is a proxy request.
51+ *
52+ * The namespace must appear as a path segment under the REST prefix
53+ * (e.g. /wp-json/<namespace>[/...]). Substring matches in query
54+ * strings, fragments, or unrelated path segments are rejected.
5155 *
5256 * @return bool
5357 */
5458 private function is_proxy_request () {
55- $ namespace = get_option ( 'plausible_analytics_proxy_resources ' )[ 'namespace ' ] ?? '' ;
59+ $ namespace = get_option ( 'plausible_analytics_proxy_resources ' )['namespace ' ] ?? '' ;
5660
5761 if ( ! $ namespace ) {
5862 return false ;
5963 }
6064
61- return strpos ( $ this ->request_uri , $ namespace ) !== false ;
65+ $ path = parse_url ( $ this ->request_uri , PHP_URL_PATH );
66+
67+ if ( ! is_string ( $ path ) || $ path === '' ) {
68+ return false ;
69+ }
70+
71+ $ rest_prefix = function_exists ( 'rest_get_url_prefix ' )
72+ ? trim ( rest_get_url_prefix (), '/ ' )
73+ : 'wp-json ' ;
74+
75+ $ expected = '/ ' . $ rest_prefix . '/ ' . trim ( $ namespace , '/ ' );
76+
77+ return $ path === $ expected
78+ || str_starts_with ( $ path , $ expected . '/ ' );
6279 }
6380
6481 /**
@@ -73,6 +90,10 @@ private function init() {
7390 /**
7491 * Filter the list of active plugins for custom endpoint requests.
7592 *
93+ * Uses basename() exact-match comparison instead of strpos(), so a
94+ * plugin file path can only match if its filename is exactly in the
95+ * allowlist.
96+ *
7697 * @param array $active_plugins The list of active plugins.
7798 *
7899 * @return array The filtered list of active plugins.
@@ -86,11 +107,8 @@ public function filter_active_plugins( $active_plugins ) {
86107 $ filtered_plugins = [];
87108
88109 foreach ( $ active_plugins as $ plugin ) {
89- foreach ( $ allowed_plugin_files as $ allowed_plugin_file ) {
90- if ( strpos ( $ plugin , $ allowed_plugin_file ) !== false ) {
91- $ filtered_plugins [] = $ plugin ;
92- break ;
93- }
110+ if ( in_array ( basename ( $ plugin ), $ allowed_plugin_files , true ) ) {
111+ $ filtered_plugins [] = $ plugin ;
94112 }
95113 }
96114
0 commit comments