Skip to content

Escaped decoded replacer URLs - #1215

Merged
pirate-bot merged 3 commits into
developmentfrom
bugfix/optimole-service/1879
Oct 30, 2026
Merged

pirate-bot merged 3 commits into
developmentfrom
bugfix/optimole-service/1879

Conversation

@girishpanchal30

Copy link
Copy Markdown
Contributor

All Submissions:

Changes proposed in this Pull Request:

Fixed a URL rewriting XSS vulnerability in Optml_Url_Replacer::build_url() by returning the original, undecoded URL from the process: early-return paths and escaping the captured id: tail with esc_url() when it is assigned. This prevents decoded Unicode escapes containing HTML characters from bypassing the existing URL escaping and reintroducing unsafe content into the page. The fix also handles process: URLs without an id: segment by returning the original URL, avoiding PHP 8 TypeErrors caused by passing an empty array to explode() or str_replace().

Closes https://github.com/Codeinwp/optimole-service/issues/1879

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes, as applicable?
  • Have you successfully ran tests with your changes locally?

@pirate-bot

pirate-bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Plugin build for ec43c1e is ready 🛎️!

@pirate-bot pirate-bot left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🟡 Changes requested

The content path is fixed, but Unicode-escaped process: image tags still emit raw HTML through the tag replacer.

Validation details
  • Files reviewed: 2/2 changed files.
  • The four new test cases pass at HEAD on PHP 8.3.36 and WordPress 7.1.4. At pr-base, two fail and two throw TypeError, so each detects the change. The A/B helper gave no run record. Logs are saved with the check.
  • Direct build_url() calls now return &, ' and %20 in the id: tail cd /workspace/checks/C3/probe && set -o pipefail; PROBE_OUT=/workspace/checks/C3/probe/head.json timeout 200 /repo/vendo… (run R4, exit 0). Content output is unchanged. Uploaded file names cannot hold these characters.
  • The image tag breakout is identical at HEAD and pr-base cd /workspace/checks/C6; for s in head base; do mv $s/tests/ProbeC6Test.php $s/tests/test-probe-c6.php; done; P=/var/www… (run R11, exit 0).
  • The earlier esc_url() fixes on the main path are intact.
Untested areas
  • JavaScript execution of the injected markup was not run in a browser.
  • The linked service issue is private and was not read.

🤖 Automated review · run code-review-agent_6ae433d8a37ee9.92952141.


🤖 Review agent — review posted ✅ on 3bd1ef32 · changes requested · 1 finding · 19 min

Run code-review-agent_6ae433d8a37ee9.92952141 · trail

Comment thread inc/url_replacer.php Resolved

@pirate-bot pirate-bot left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🟡 Changes requested

The earlier image tag finding is still open: a decoded space in a process: image src passes the new guard. See #1215 (comment).

Validation details
  • Files reviewed: 2/2 files changed since the prior review. One likely row stays unchecked: the decoded apostrophe skip.
  • The new test passes at HEAD. Each data set fails at pr-base and at 3bd1ef3 on its <svg assertion. The A/B helper gave no run record.
  • The thread's "><svg tag is blocked at HEAD `mkdir -p /workspace/checks/R1/probe && cat > /workspace/checks/R1/probe/ProbeR1Test.php <<'PHP'
Untested areas - The decoded apostrophe skip: HEAD no longer rewrites a slashed `o\u0027brien.jpg` src. No producer of that value was found. - JavaScript execution of the injected attribute was not run in a browser. - The full `the_content` filter was not run.
🤖 Automated review · run code-review-agent_6ae43d18bd16a8.77443467. --- **🤖 Review agent** — review posted ✅ on `186f1dc2` · [changes requested · 0 findings](https://github.com//pull/1215#pullrequestreview-5709119086) · 21 min Run `code-review-agent_6ae43d18bd16a8.77443467` · [trail](https://agents.vertistudio.com/admin/trails/github-pr/Codeinwp-optimole-wp-1215)

@pirate-bot pirate-bot left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🟢 Approved

The PR passes: the new guard blocks decoded whitespace in slashed image tags, which fixes the earlier image tag finding.

Validation details
  • Files reviewed: 2/2 files changed since the prior review. One row stays unchecked: consumer: Optml_Url_Replacer::build_url() return changed.
  • The changed test passes at HEAD set -o pipefail; cd /repo && timeout 300 vendor/bin/phpunit --do-not-cache-result --filter 'test_unicode_escaped_image_t… printed OK (4 tests, 4 assertions) (run R8).
  • The changed test fails at pr-base set -o pipefail; B=/workspace/checks/R3/base-tree; L=/var/www/html/wp-content/plugins/optimole-wp; rm -f $L; ln -sfn $B … printed Tests: 4, Assertions: 4, Failures: 4. (run R7).
  • A HEAD probe left the space, tab, newline and "><svg tags unchanged in both lazy-load modes (R4). At pr-base they came out decoded (R5).
  • The url_replacer.php checks of run code-review-agent_6ae43d18bd16a8.77443467 are reused, not rerun.
Untested areas
  • Consumer: Optml_Url_Replacer::build_url() return changed. The non-tag consumers were not re-checked in this run.
  • Slashed src values with a decoded space or apostrophe are no longer optimized. No producer of these values was found.
  • A decoded backslash before the closing quote reaches output at HEAD and pr-base alike. It is not new in this change.
  • JavaScript execution was not run in a browser.

🤖 Automated review · run code-review-agent_6ae44587292f22.95417497.


🤖 Review agent — review posted ✅ on ec43c1ec · approved · 0 findings · 10 min

Run code-review-agent_6ae44587292f22.95417497 · trail

@pirate-bot
pirate-bot merged commit 398e24b into development Oct 30, 2026
14 checks passed
@pirate-bot
pirate-bot deleted the bugfix/optimole-service/1879 branch October 30, 2026 18:03
@pirate-bot

Copy link
Copy Markdown
Collaborator

🎉 This PR is included in version 4.2.18 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@pirate-bot pirate-bot added the released Indicate that an issue has been resolved and released in a particular version of the product. label Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

released Indicate that an issue has been resolved and released in a particular version of the product.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants