From 59a63e414c821836909608ac2f8db7d5524cdc84 Mon Sep 17 00:00:00 2001 From: Faisal Ahammad Date: Thu, 12 Feb 2026 22:44:34 +0600 Subject: [PATCH 1/4] Fix #1156: Enable EnqueuedResourceOffloading check to detect external CDN usage This commit enables the existing EnqueuedResourceOffloadingSniff in the plugin-check ruleset to detect when plugins load external assets from third-party CDNs without user consent, addressing a privacy guideline violation (WordPress.org guideline #7). The sniff already existed and was fully functional with comprehensive unit tests, but was not included in the plugin-check.ruleset.xml file. This simple addition now ensures PCP will flag CDN usage from jsdelivr, unpkg, cloudflare, bootstrapcdn, and 20+ other known CDN services. --- phpcs-rulesets/plugin-check.ruleset.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpcs-rulesets/plugin-check.ruleset.xml b/phpcs-rulesets/plugin-check.ruleset.xml index ab760d7d5..e387c77fc 100644 --- a/phpcs-rulesets/plugin-check.ruleset.xml +++ b/phpcs-rulesets/plugin-check.ruleset.xml @@ -158,4 +158,9 @@ + + + 7 + + From 5efd56a570176b754c81ba01741e5a75f4570098 Mon Sep 17 00:00:00 2001 From: Faisal Ahammad Date: Wed, 4 Mar 2026 19:47:55 +0600 Subject: [PATCH 2/4] Improve OffloadingSniff to detect CDN URLs in PHP strings --- phpcs-rulesets/plugin-check.ruleset.xml | 5 ---- .../Sniffs/CodeAnalysis/OffloadingSniff.php | 28 ++++++++++--------- .../Tests/CodeAnalysis/OffloadingUnitTest.inc | 22 +++++++++++++++ .../Tests/CodeAnalysis/OffloadingUnitTest.php | 9 ++++-- 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/phpcs-rulesets/plugin-check.ruleset.xml b/phpcs-rulesets/plugin-check.ruleset.xml index e387c77fc..ab760d7d5 100644 --- a/phpcs-rulesets/plugin-check.ruleset.xml +++ b/phpcs-rulesets/plugin-check.ruleset.xml @@ -158,9 +158,4 @@ - - - 7 - - diff --git a/phpcs-sniffs/PluginCheck/Sniffs/CodeAnalysis/OffloadingSniff.php b/phpcs-sniffs/PluginCheck/Sniffs/CodeAnalysis/OffloadingSniff.php index eb4b61450..d05a4b20a 100644 --- a/phpcs-sniffs/PluginCheck/Sniffs/CodeAnalysis/OffloadingSniff.php +++ b/phpcs-sniffs/PluginCheck/Sniffs/CodeAnalysis/OffloadingSniff.php @@ -65,19 +65,7 @@ public function process_token( $stackPtr ) { return; } - // Only match HTML markup not arbitrary strings, as those could be covered by EnqueuedResourceOffloadingSniff already. - - if ( - false === strpos( $content, 'get_offloading_services_pattern(); $matches = array(); @@ -92,6 +80,20 @@ public function process_token( $stackPtr ) { return ( $end_ptr + 1 ); } + // Second check: For HTML markup strings only, also check file extension-based patterns. + // This is limited to HTML context to avoid false positives on arbitrary URLs. + + if ( + false === strpos( $content, ' + + 'https://cdn.jsdelivr.net/npm/intl-tel-input@21.2.4/build/js/intlTelInput.min.js', +); + +// CDN URL in array assignment for CSS. +$assets[] = array( + 'type' => 'css', + 'url' => 'https://cdn.jsdelivr.net/npm/intl-tel-input@21.2.4/build/css/intlTelInput.css', +); + +// CDN URL in variable assignment. +$script_url = 'https://unpkg.com/some-library@1.0.0/dist/lib.js'; + +// Non-CDN URL should NOT be flagged. +$api_url = 'https://api.example.com/data'; + +// Non-CDN safe URL should NOT be flagged. +$safe_url = 'https://mysite.com/wp-content/themes/my-theme/style.css'; diff --git a/phpcs-sniffs/PluginCheck/Tests/CodeAnalysis/OffloadingUnitTest.php b/phpcs-sniffs/PluginCheck/Tests/CodeAnalysis/OffloadingUnitTest.php index 6b7c77572..c8f1aa48d 100644 --- a/phpcs-sniffs/PluginCheck/Tests/CodeAnalysis/OffloadingUnitTest.php +++ b/phpcs-sniffs/PluginCheck/Tests/CodeAnalysis/OffloadingUnitTest.php @@ -23,9 +23,12 @@ final class OffloadingUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 1 => 1, - 3 => 1, - 5 => 1, + 1 => 1, + 3 => 1, + 5 => 1, + 11 => 1, + 17 => 1, + 21 => 1, ); } From a9154b76d0ce51acde7a4f29fce0c8156cec7c7e Mon Sep 17 00:00:00 2001 From: Faisal Ahammad Date: Wed, 4 Mar 2026 20:06:45 +0600 Subject: [PATCH 3/4] Fix duplicate reporting overlap with EnqueuedResourceOffloadingSniff --- .../Sniffs/CodeAnalysis/OffloadingSniff.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/phpcs-sniffs/PluginCheck/Sniffs/CodeAnalysis/OffloadingSniff.php b/phpcs-sniffs/PluginCheck/Sniffs/CodeAnalysis/OffloadingSniff.php index d05a4b20a..9830f23e6 100644 --- a/phpcs-sniffs/PluginCheck/Sniffs/CodeAnalysis/OffloadingSniff.php +++ b/phpcs-sniffs/PluginCheck/Sniffs/CodeAnalysis/OffloadingSniff.php @@ -65,6 +65,20 @@ public function process_token( $stackPtr ) { return; } + // Skip check if the string is within wp_enqueue_script/etc function calls, + // as EnqueuedResourceOffloadingSniff already handles those and we want to avoid double reporting. + if ( isset( $this->tokens[ $stackPtr ]['nested_parenthesis'] ) ) { + foreach ( $this->tokens[ $stackPtr ]['nested_parenthesis'] as $opener => $closer ) { + $prev = $this->phpcsFile->findPrevious( \PHP_CodeSniffer\Util\Tokens::$emptyTokens, ( $opener - 1 ), null, true ); + if ( false !== $prev && \T_STRING === $this->tokens[ $prev ]['code'] ) { + $function_name = $this->tokens[ $prev ]['content']; + if ( in_array( $function_name, array( 'wp_enqueue_script', 'wp_enqueue_style', 'wp_register_script', 'wp_register_style' ), true ) ) { + return ( $end_ptr + 1 ); + } + } + } + } + // First check: Always check against known offloading services pattern for all strings. $pattern = $this->get_offloading_services_pattern(); From 69720c62ed069364c85ed096ce62068d0e84afee Mon Sep 17 00:00:00 2001 From: Faisal Ahammad Date: Wed, 4 Mar 2026 20:13:45 +0600 Subject: [PATCH 4/4] Fix PHPCS error: use imported class name Tokens instead of FQN --- .../PluginCheck/Sniffs/CodeAnalysis/OffloadingSniff.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpcs-sniffs/PluginCheck/Sniffs/CodeAnalysis/OffloadingSniff.php b/phpcs-sniffs/PluginCheck/Sniffs/CodeAnalysis/OffloadingSniff.php index 9830f23e6..a50776dbe 100644 --- a/phpcs-sniffs/PluginCheck/Sniffs/CodeAnalysis/OffloadingSniff.php +++ b/phpcs-sniffs/PluginCheck/Sniffs/CodeAnalysis/OffloadingSniff.php @@ -69,7 +69,7 @@ public function process_token( $stackPtr ) { // as EnqueuedResourceOffloadingSniff already handles those and we want to avoid double reporting. if ( isset( $this->tokens[ $stackPtr ]['nested_parenthesis'] ) ) { foreach ( $this->tokens[ $stackPtr ]['nested_parenthesis'] as $opener => $closer ) { - $prev = $this->phpcsFile->findPrevious( \PHP_CodeSniffer\Util\Tokens::$emptyTokens, ( $opener - 1 ), null, true ); + $prev = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $opener - 1 ), null, true ); if ( false !== $prev && \T_STRING === $this->tokens[ $prev ]['code'] ) { $function_name = $this->tokens[ $prev ]['content']; if ( in_array( $function_name, array( 'wp_enqueue_script', 'wp_enqueue_style', 'wp_register_script', 'wp_register_style' ), true ) ) {