Skip to content

Regression: Non UTF-8 encoded URI component still throws "Unable to serialize value" in CatalogWidget on 2.4.7-p5 #40824

@lbajsarowicz

Description

@lbajsarowicz

Preconditions and environment

Steps to reproduce

  1. Add a "Catalog Products List" widget to any CMS page (e.g. homepage).
  2. Open that page with a malformed UTF-8 byte sequence in a query parameter, e.g.:
    • https://example.test/?q=%C0%AF (overlong UTF-8 slash)
    • https://example.test/?dclid=%EDclid
    • https://example.test/?utm_source=%E0
    • https://example.test/?fbclid=foo% (dangling percent)
  3. Observe the rendered page and var/log/system.log.

These URLs occur in the wild from truncated Facebook / Google Ads tracking parameters (fbclid, gclid, dclid, utm_*), broken share buttons, and bot scanners.

Expected result

Widget renders normally. Malformed UTF-8 in the query string must not break server-side block rendering.

Actual result

Widget output is replaced by the generic CMS fallback message ("Sorry, we cannot generate the content...", localized) and the following entry is logged:

main.CRITICAL: InvalidArgumentException: Unable to serialize value.
Error: Malformed UTF-8 characters, possibly incorrectly encoded
  in vendor/magento/framework/Serialize/Serializer/Json.php:26

Abbreviated stack trace:

#0  vendor/magento/module-catalog-widget/Block/Product/ProductsList.php(235):
      Magento\Framework\Serialize\Serializer\Json->serialize()
#5  vendor/magento/framework/View/Element/AbstractBlock.php(1063):
      ProductsList->getCacheKeyInfo()
#6  AbstractBlock.php(1150): AbstractBlock->getCacheKey()
#7  AbstractBlock.php(676):  AbstractBlock->_loadCache()
#8  Interceptor->___callParent() → toHtml()
...
#82 vendor/magento/framework/App/Http.php(120): renderResult()
#92 pub/index.php(30): Bootstrap->run()

Root cause

Magento\CatalogWidget\Block\Product\ProductsList::getCacheKeyInfo() (line 235 of current 2.4-develop) passes raw $_GET (via $this->getRequest()->getParams()) to the serializer:

return [
    ...
    $this->json->serialize($this->getRequest()->getParams()),
    ...
];

Magento\Framework\Serialize\Serializer\Json::serialize() calls json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) with no JSON_INVALID_UTF8_SUBSTITUTE / JSON_INVALID_UTF8_IGNORE flag. Any byte sequence in $_GET that is not valid UTF-8 causes json_encode to return false with JSON_ERROR_UTF8, which the serializer rethrows as InvalidArgumentException.

Because getCacheKeyInfo() is called from AbstractBlock::getCacheKey()_loadCache()toHtml(), the entire block fails to render and Magento falls back to the generic error template.

The same underlying defect surfaces in any other code path that serializes user-controlled input (request params, raw cookie values, certain redirect URLs). See also the ReCaptcha variant reported in #30486.

Related / prior reports

Suggested directions (not a fix proposal)

Listed only to clarify scope of the regression:

  • Magento\Framework\Serialize\Serializer\Json::serialize() — pass JSON_INVALID_UTF8_SUBSTITUTE (or wrap in a guard that returns a safe placeholder).
  • Magento\CatalogWidget\Block\Product\ProductsList::getCacheKeyInfo() — sanitize / hash $_GET instead of serializing it raw. Including the full $_GET in the cache key is also a separate performance / cache-fragmentation concern, since any unique URL parameter creates a new cache entry.

Severity / impact

  • Reliability: any URL with malformed UTF-8 from third-party traffic sources renders an error region instead of the home / category / CMS page where the widget is placed.
  • Reachability: trivial. A single crafted GET parameter is enough; no auth, no preconditions beyond the widget being on the page.
  • Observability cost: every hit logs a CRITICAL to system.log, which can drown application logs under bot traffic.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area: ContentComponent: WidgetIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedPriority: P2A defect with this priority could have functionality issues which are not to expectations.Progress: ready for groomingReported on 2.4.7-p5Indicates original Magento version for the Issue report.Reproduced on 2.4.xThe issue has been reproduced on latest 2.4-develop branch

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Ready for Development

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions