Skip to content

Upd. ContactEncoder. Imrove area-label processing. - #866

Merged
svfcode merged 8 commits into
fixfrom
upd-ce5
Sep 9, 2026
Merged

Upd. ContactEncoder. Imrove area-label processing.#866
svfcode merged 8 commits into
fixfrom
upd-ce5

Conversation

@svfcode

@svfcode svfcode commented Aug 24, 2026

Copy link
Copy Markdown
Member

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens ContactsEncoder’s aria-label placeholder handling to prevent attacker-controlled placeholder collisions during the “hide/restore aria-label” round-trip, and adds regression tests covering both normal aria-label preservation and a CVE-style markup breakout/XSS payload.

Changes:

  • Replace sequential ct_temp_aria_N placeholders with unguessable %%APBCT_ARIA_<random>%% placeholders.
  • Restore aria-label placeholders only at the first occurrence to avoid rewriting planted tokens.
  • Add PHPUnit coverage for aria-label email preservation and for the reported CVE-2026-77830 payload patterns.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
tests/ApbctWP/ContactsEncoder/TestContactsEncoder.php Adds regression tests for aria-label preservation and for preventing token-collision / markup-breakout behavior.
lib/Cleantalk/Common/ContactsEncoder/ContactsEncoder.php Switches aria-label placeholder generation to random, and updates restoration logic to be collision-resistant.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread lib/Cleantalk/Common/ContactsEncoder/ContactsEncoder.php
@codecov

codecov Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 27.14286% with 51 lines in your changes missing coverage. Please review.
✅ Project coverage is 30.05%. Comparing base (5319141) to head (016187d).
⚠️ Report is 6 commits behind head on fix.

Files with missing lines Patch % Lines
lib/Cleantalk/Common/Helper.php 20.00% 8 Missing ⚠️
inc/cleantalk-settings.php 42.85% 4 Missing ⚠️
...leantalk/Antispam/Integrations/AmemberRegister.php 0.00% 4 Missing ⚠️
...sEncoder/Integrations/CEIntegrationGridBuilder.php 42.85% 4 Missing ⚠️
...actsEncoder/Shortcodes/ExcludedEncodeContentSC.php 0.00% 4 Missing ⚠️
inc/cleantalk-common.php 0.00% 3 Missing ⚠️
.../Antispam/Integrations/CleantalkWpDieOnComment.php 0.00% 3 Missing ⚠️
inc/cleantalk-wpcli.php 0.00% 2 Missing ⚠️
...b/Cleantalk/Antispam/Integrations/ElfsightForm.php 0.00% 2 Missing ⚠️
lib/Cleantalk/Antispam/Integrations/Forminator.php 0.00% 2 Missing ⚠️
... and 14 more

❌ Your patch check has failed because the patch coverage (27.14%) is below the target coverage (70.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff              @@
##                fix     #866      +/-   ##
============================================
+ Coverage     30.02%   30.05%   +0.02%     
- Complexity     6541     6544       +3     
============================================
  Files           289      289              
  Lines         26247    26262      +15     
============================================
+ Hits           7880     7892      +12     
- Misses        18367    18370       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread lib/Cleantalk/Common/ContactsEncoder/ContactsEncoder.php

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread lib/Cleantalk/Common/ContactsEncoder/ContactsEncoder.php Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

tests/ApbctWP/ContactsEncoder/TestContactsEncoder.php:253

  • The regex />aria-label=/ only detects a breakout when there is no whitespace/newline between > and aria-label and when aria-label has no whitespace around =. Using a whitespace-tolerant pattern makes the regression test stronger for markup injection cases.

This issue also appears on line 267 of the same file.

        $result = $this->contacts_encoder->modifyContent($payload);

        $this->assertStringContainsString('ct_temp_aria_0', $result);
        $this->assertNotRegExp('/>aria-label=/', $result);
    }

tests/ApbctWP/ContactsEncoder/TestContactsEncoder.php:269

  • Same as above: preg_match('/>aria-label=/') can miss injected > aria-label = variants. Consider making the detection whitespace-tolerant so the test fails on more real-world breakout formats.
        $planted_token_preserved = strpos($result, 'ct_temp_aria_0') !== false;
        $breakout_injected = (bool) preg_match('/>aria-label=/', $result);

Comment thread lib/Cleantalk/Common/ContactsEncoder/ContactsEncoder.php

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

lib/Cleantalk/Common/ContactsEncoder/ContactsEncoder.php:897

  • handleAriaLabelContent() (and restoreAriaLabelPlaceholder()) assume $content is always a string, but callers pass the result of preg_replace_callback(), which can be null on PCRE errors (e.g., backtrack/recursion limit). Passing null into strpos()/substr() can raise a TypeError and break rendering. Consider coercing $content to string at the start of handleAriaLabelContent() to avoid fatals during restore.
    private function handleAriaLabelContent($content, $reverse = false)
    {
        if ( !$reverse ) {

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

lib/Cleantalk/Common/ContactsEncoder/ContactsEncoder.php:259

  • When both email and phone encoding are enabled, aria-label placeholders are restored at the end of modifyGlobalEmails(), before modifyGlobalPhoneNumbers() runs. That means phone-number encoding can still rewrite phone numbers inside aria-label, which contradicts the intent of hiding/restoring aria-label around encoding passes.
        // modify content to prevent aria-label replaces by hiding it
        if ( $this->do_encode_emails || $this->do_encode_phones ) {
            $content = $this->handleAriaLabelContent($content);
        }

tests/ApbctWP/ContactsEncoder/TestContactsEncoder.php:232

  • Test coverage currently verifies aria-label preservation for emails, but not for phone numbers. Since modifyContent() now also applies aria-label placeholder handling when phone encoding is enabled, add a test case asserting that an aria-label containing a phone number is preserved when phone encoding (and especially email+phone encoding together) is enabled.
    public function testModifyContentPreservesAriaLabelWithEmail()
    {
        $email = 'info@example.com';
        $content = '<button aria-label="Contact us at ' . $email . '">Click</button>';

@svfcode
svfcode merged commit 4a127fb into fix Sep 9, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants