Connection::isBot() matches "Motor" inside "motorola": carts are never updated for Motorola phones browsing from the Instagram/Facebook in-app browser
Prerequisites
- I understand and accept the project's code of conduct.
- I have already searched in existing issues and found no previous report of this bug.
Describe the bug and add attachments
Connection::isBot() (classes/Connection.php) matches its bot list against the user agent without word
boundaries and case-insensitively. The list contains the entry Motor (an old crawler), which therefore
matches inside the string motorola.
CartController::updateCart() skips the whole cart update when Connection::isBot() returns true:
// Update the cart ONLY if it's not a bot, in order to avoid ghost carts
if (!Connection::isBot()
&& !$this->errors
&& !($this->context->customer->isLogged() && !$this->isTokenValid())
) {
if (Tools::getIsset('add') || Tools::getIsset('update')) {
$this->processChangeProductInCart();
}As a consequence, every visitor whose user agent contains "motorola" can never add anything to the cart. The request returns HTTP 200, no error is raised, the "product added" modal is displayed by the theme, and the cart silently stays empty. Nothing appears in any log, which makes it very hard to diagnose.
This is not an edge case: the Instagram and Facebook in-app browsers are the only ones that put the manufacturer in the user agent, e.g.
Mozilla/5.0 (Linux; Android 16; moto g77 Build/W2WIS36.43-92-1; wv) AppleWebKit/537.36 (KHTML, like Gecko)
Version/4.0 Chrome/153.0.8010.26 Mobile Safari/537.36 Instagram 446.0.0.49.77 Android
(36/16; 390dpi; 1080x2352; motorola; moto g77; naples; mt6835; it_IT; 1061744266; IABMV/1)The regular Chrome user agent on the same phone only contains the model (moto g77), not motorola, so the
same customer can buy from the normal browser but not from the app — which is exactly how our customers
described it ("from my computer it works, from my phone it doesn't").
The entry webs in the same list has the same problem: it matches inside MMWEBSDK, present in the WeChat
in-app browser user agent.
Impact we measured on a production shop
Over one day: 8,779 requests from user agents containing motorola (6,070 from the Instagram in-app browser,
2,670 from the Facebook one) plus 920 from the webs case — 0.63% of all traffic unable to purchase.
Order-confirmation rate inside the Instagram browser was 1.27% against 4.3–4.5% for every other browser.
Two customers reported it as "it doesn't add the product to the cart"; both own a Motorola phone.
Possible fix
Add word boundaries to the ambiguous entries of the regex in Connection::isBot(), e.g. \bMotor\b and
\bwebs\b. Real crawlers presenting those names are still detected; phones are not. We are running this as an
override in production and verified that Googlebot and a real Motor/0.2 libwww-perl user agent are still
recognised as bots.
More generally, the list contains several short, generic words (legs, nil, none, sift, speedy,
grabber, webs, Motor…) matched without boundaries, so other false positives are likely as devices and
in-app browsers keep changing their user agents.
Steps to reproduce
- Take any shop with combinations enabled.
- Send an add-to-cart request with a normal mobile user agent:
curl -s -A "Mozilla/5.0 (Linux; Android 16; moto g77) AppleWebKit/537.36 Chrome/153.0 Mobile Safari/537.36" \
-X POST "https://example.com/cart" -H "X-Requested-With: XMLHttpRequest" \
--data "controller=cart&add=1&action=update&ajax=1&id_product=123&id_product_attribute=456&qty=1" → the JSON response contains the product, products_count is 1.
- Send the exact same request, only adding the word
motorolato the user agent:
curl -s -A "Mozilla/5.0 (Linux; Android 16; moto g77) AppleWebKit/537.36 Chrome/153.0 Mobile Safari/537.36 motorola" \
-X POST "https://example.com/cart" -H "X-Requested-With: XMLHttpRequest" \
--data "controller=cart&add=1&action=update&ajax=1&id_product=123&id_product_attribute=456&qty=1" → HTTP 200, hasError is false, but the cart is still empty (products_count = 0) and no cart row is
created in the database.
The same happens with any user agent containing motorola, and with MMWEBSDK (because of the webs entry).
Other manufacturers (samsung, LG, HTC, Xiaomi, huawei, OnePlus) are not affected.
Expected behavior
A real customer using a Motorola phone (or the WeChat browser) can add products to the cart. Only actual crawlers are treated as bots.
Actual Result
No response
PrestaShop version where the bug happens
9.x (the same list and the same call in CartController are present in 1.7.x and 8.x as well).
How have you installed PrestaShop
No response
PHP version(s) where the bug happened
No response
Your company or customer's name goes here (if applicable).
Massimo Manarini
Source: PrestaShop/PrestaShop