Post by FallingUp » Thu Jul 29, 2021 4:19 am

straightlight wrote:
Thu Jul 29, 2021 4:11 am
FallingUp wrote:
Thu Jul 29, 2021 3:00 am
straightlight wrote:
Wed Jul 28, 2021 8:08 pm


Which checkout module?
Ajax Best Checkout - Easy Quick n Boosted on opencart
https://www.opencart.com/index.php?rout ... n_id=20736

It's possbile that this annoying bug can be a problem of Opencart 3.0.2.0 itself or the checkout module.
Either:

- Contact the extension developer to resolve this issue
- Install a fresh Opencart store on a test server, not sub-domain, with the checkout module you are using
- Uninstall the checkout module and see if the problem you describe persists
- Create a new service request in the Commercial Support section of the forum to have this issue investigated as a custom job
Please see my reply above. It can be fixed with adding some lines of codes to the payment extension. Isn't it something that can be done to Opencart files itself? This must be a known bug, but I cannot reproduce this on my test site as it's periodic with certain weird factors

Newbie

Posts

Joined
Mon Jan 01, 2018 5:12 am

Post by straightlight » Thu Jul 29, 2021 4:26 am

FallingUp wrote:
Thu Jul 29, 2021 4:19 am
straightlight wrote:
Thu Jul 29, 2021 4:11 am
FallingUp wrote:
Thu Jul 29, 2021 3:00 am


Ajax Best Checkout - Easy Quick n Boosted on opencart
https://www.opencart.com/index.php?rout ... n_id=20736

It's possbile that this annoying bug can be a problem of Opencart 3.0.2.0 itself or the checkout module.
Either:

- Contact the extension developer to resolve this issue
- Install a fresh Opencart store on a test server, not sub-domain, with the checkout module you are using
- Uninstall the checkout module and see if the problem you describe persists
- Create a new service request in the Commercial Support section of the forum to have this issue investigated as a custom job
Please see my reply above. It can be fixed with adding some lines of codes to the payment extension. Isn't it something that can be done to Opencart files itself? This must be a known bug, but I cannot reproduce this on my test site as it's periodic with certain weird factors
Without knowing the source of the issue, and without troubleshooting the problem, where the reported issue stands, what you are presuming as an known bug would be inaccurate. Which is why, the four possibilities above were provided unless you could provide error log entries that may prove otherwise.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by ADD Creative » Thu Jul 29, 2021 5:32 am

As I have already said, it impossible for the OpenCart core to use the same order ID twice. Without knowing what your payment and checkout extensions change, it's impossible to add code to the core to stop it. I would suggest it could be caused by your payment extension being incomparable with your checkout extension.

Having looked at the A and B files. It also looks like it could have an SQL injection vulnerability.

I would possibly look for a different payment module.

www.add-creative.co.uk


Expert Member

Posts

Joined
Sat Jan 14, 2012 1:02 am
Location - United Kingdom

Post by LVL91 » Tue Aug 03, 2021 12:45 am

I have the same issue with OC 3.0.3.7 and I am not sure if Journal 3 or any other checkout extension is the issue. I think I have pin pointed the issue and it seems to be quite simple. You get the issue when the customer is not redirected to the success page. It seems the only customer-related part in the code that clears the order_id in the session is the logout controller or the success controller. We however have the following cases when the customer is NOT redirected to the success page:
1. When the customer simply closes the browser after payment was made (the customer will wait for a confirmation and the webhook of the payment gateway will take care of the rest). This is expected behavior from the customer's perspective for many of the payment gateways we use, we can't blame the customer for not following the "normal" checkout up towards the success page.
2. When the webhook is not processed properly, the customer doesn't get redirected to the success page, but a later webhook mostly confirms the order anyway. This is some glitch in the network, either high load or network issues. We ask our customers to wait for 15 minutes to check if they receive a confirmation email, if they get the confirmation the payment was processed properly. The order_id however is not unset in the session.

So, should the customer make a new order within expiring of the order(gc_maxlifetime), the order is overwritten due to the order_id being the same in the session. I remember the old opencart (1.5.6) didn't remember the order_id and always created a new order_id. Qphoria made a vqmod for this to remember the order_id thus to avoid database pollution. Perhaps Journal 3 and other checkout extensions use the same technique, but forget to unset the order_id in the session whenever an order has been confirmed, but I think it's mostly due to the payment gateways not always redirecting to the success page. I have to do some research for the best possible place in the code to clear the matching order_id in sessions that is linked to a confirmed order.

Edit: In my case it is in fact Journal 3 in combination with the payment gateway which is causing the problem, see post below.
Last edited by LVL91 on Tue Aug 03, 2021 2:52 am, edited 2 times in total.

New member

Posts

Joined
Fri Feb 21, 2014 9:12 am

Post by JNeuhoff » Tue Aug 03, 2021 1:07 am

Well, you could easily test it. Do a checkout, and then close your web browser before reaching the checkout/success page.

Then, sometime later, re-open the same web browser. Is the cart still there then?

You may also want to check your server's access.log, does it include a call to the checkout/success page, even though you closed your web browser before that? I think you'll still see the access to the checkout/success controller logged in there!

Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig


User avatar
Guru Member

Posts

Joined
Wed Dec 05, 2007 3:38 am


Post by straightlight » Tue Aug 03, 2021 1:27 am

LVL91 wrote:
Tue Aug 03, 2021 12:45 am
I have the same issue with OC 3.0.3.7 and I am not sure if Journal 3 or any other checkout extension is the issue. I think I have pin pointed the issue and it seems to be quite simple. You get the issue when the customer is not redirected to the success page. It seems the only customer-related part in the code that clears the order_id in the session is the logout controller or the success controller. We however have the following cases when the customer is NOT redirected to the success page:
1. When the customer simply closes the browser after payment was made (the customer will wait for a confirmation and the webhook of the payment gateway will take care of the rest). This is expected behavior from the customer's perspective for many of the payment gateways we use, we can't blame the customer for not following the "normal" checkout up towards the success page.
2. When the webhook is not processed properly, the customer doesn't get redirected to the success page, but a later webhook mostly confirms the order anyway. This is some glitch in the network, either high load or network issues. We ask our customers to wait for 15 minutes to check if they receive a confirmation email, if they get the confirmation the payment was processed properly. The order_id however is not unset in the session.

So, should the customer make a new order within expiring of the order(gc_maxlifetime), the order is overwritten due to the order_id being the same in the session. I remember the old opencart (1.5.6) didn't remember the order_id and always created a new order_id. Qphoria made a vqmod for this to remember the order_id thus to avoid database pollution. Perhaps Journal 3 and other checkout extensions use the same technique, but forget to unset the order_id in the session whenever an order has been confirmed, but I think it's mostly due to the payment gateways not always redirecting to the success page. I have to do some research for the best possible place in the code to clear the matching order_id in sessions that is linked to a confirmed order.
Webhooks are still relatives to specific payment services. Therefore, what you are addressing about originates from a specific extension where the order ID can be re-compared with the use of an Event prior to unset the created and identical order ID from the success page.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by ADD Creative » Tue Aug 03, 2021 2:06 am

LVL91 wrote:
Tue Aug 03, 2021 12:45 am
I have the same issue with OC 3.0.3.7 and I am not sure if Journal 3 or any other checkout extension is the issue. I think I have pin pointed the issue and it seems to be quite simple. You get the issue when the customer is not redirected to the success page. It seems the only customer-related part in the code that clears the order_id in the session is the logout controller or the success controller. We however have the following cases when the customer is NOT redirected to the success page:
1. When the customer simply closes the browser after payment was made (the customer will wait for a confirmation and the webhook of the payment gateway will take care of the rest). This is expected behavior from the customer's perspective for many of the payment gateways we use, we can't blame the customer for not following the "normal" checkout up towards the success page.
2. When the webhook is not processed properly, the customer doesn't get redirected to the success page, but a later webhook mostly confirms the order anyway. This is some glitch in the network, either high load or network issues. We ask our customers to wait for 15 minutes to check if they receive a confirmation email, if they get the confirmation the payment was processed properly. The order_id however is not unset in the session.

So, should the customer make a new order within expiring of the order(gc_maxlifetime), the order is overwritten due to the order_id being the same in the session. I remember the old opencart (1.5.6) didn't remember the order_id and always created a new order_id. Qphoria made a vqmod for this to remember the order_id thus to avoid database pollution. Perhaps Journal 3 and other checkout extensions use the same technique, but forget to unset the order_id in the session whenever an order has been confirmed, but I think it's mostly due to the payment gateways not always redirecting to the success page. I have to do some research for the best possible place in the code to clear the matching order_id in sessions that is linked to a confirmed order.
OpenCart still does create a new order ID for each order. So the issue is with the theme/extension/payment module. You may not find a place to clear the order_id in a sessions other than where it already is.

This is because if a payment doesn't require the customer to return to store and uses a callback instead (such as PayPal Standard). There is no way to access the customer's session from the callback.

If the theme/extension/payment module wants to add orders in a different way, then it need to add something to prevent duplicates from happening. Only overwriting orders with a status of 0 would be a start.

If you do need a workaround, maybe clearing the order_id in the session on entering checkout. But if the checkout has been modified this may not help.

www.add-creative.co.uk


Expert Member

Posts

Joined
Sat Jan 14, 2012 1:02 am
Location - United Kingdom

Post by LVL91 » Tue Aug 03, 2021 2:47 am

I did some further investigation and couldn't quite believe it, it's Journal 3 which is causing the problem, again. I also had this problem to some extend with Journal 2 on 1.5.6 actually and I honestly did not expect them to still have about the same issue many versions later. In my case it's a combination of Journal 3 quickcheckout with a payment method which does not return to the success page and doesn't clear the order_id in the session. I am working on a simple fix now and will first contact the journal 3 developers to give them a chance to provide the fix to all their customers. For now I will not disclose any details due to the severity of the bug (I think it's quite bad). Most likely all Journal 3 quickcheckout users with payment gateways that use webhooks to confirm the order and don't require a redirect to the success page are affected by this.

This bug could also exist with other checkout extensions. I guess poorly written checkout extensions with semi-poorly written payment gateways can cause severe bugs. To be continued...

Update 1: Simple fix done for my website which should fix 99,9% of the issues. After further consideration I think it could still be exploited and I have to come up with a better fix to solve this for all situations. Since I am now on vacation I will look into this further after my vacation.

New member

Posts

Joined
Fri Feb 21, 2014 9:12 am

Post by JNeuhoff » Tue Aug 03, 2021 6:35 am

A better fix would then be not to use the Journal3 framework at all, and use OpenCart instead. After all, payment methods and other extensions are written for OpenCart, not the Journal framework.

Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig


User avatar
Guru Member

Posts

Joined
Wed Dec 05, 2007 3:38 am


Post by LVL91 » Tue Aug 03, 2021 11:10 pm

It would indeed be better not to use it all, but the OC default is not very user friendly in my opinion. Sad thing is that I'm afraid other quick checkout extensions have the same issues, e.g. as said some posts ago about the "Quick N boosted" checkout. I had the same issue with one of the earlier versions of the Dreamvention Ajax quick checkout, I then switched to Journal 2 and started to use that quick checkout. I have a solution in mind for which I'm quite sure it would solve all related issues. Same code, with minor modification, should work for other checkout extensions as well then.

New member

Posts

Joined
Fri Feb 21, 2014 9:12 am

Post by LVL91 » Wed Aug 11, 2021 11:53 am

A little update, I have contacted Digital Atelier about this issue and made my own modifications to work around this issue for basically any use case I can think of to avoid this from happening and perhaps even being exploited. I will keep you updated on this issue, also regarding my contact with the Journal 3 developers.

New member

Posts

Joined
Fri Feb 21, 2014 9:12 am

Post by LVL91 » Fri Aug 13, 2021 1:19 am

This will probably be the last update for some time. The reply from the Journal 3 developers was not quite what I was expecting. Therefore I will explain what issues I had, explain the root cause with possible exploits involved and attach a OCMOD with fixes for these issues.

I had some issues with orders being overwritten, yet already confirmed, processed and shipped. As it turns out, the Quick checkout from Journal 3 has a major flaw. It uses the order_id in the session (if available) to update and confirm the order on the checkout page, but due to payment gateways, our customers will not always return to the success page. Webhooks usually take care of order confirmation, so quite some customers will simply do the payment, close the browser and never reach the success page. Due to this use case, the order_id never gets cleared in the session (by loading the success page) and the next time the checkout is used to edit anything in an order, it uses the exact same order_id to overwrite the entire order with the contents of the cart and other order data. There are no checks done for the order_id in the session being valid. This is extremely dangerous as customers will have a way of editing orders, even after they have been confirmed and paid. As a result stock levels don't match anymore and loss of money could be involved.

This issue doesn't exist (to some extend) as long as the customer will always follow the complete steps from checkout-->payment gateway-->success page as this will clear the order_id in the session. This is why you probably haven't heard from it much, also due to sessions expiring over time which also clears the session data.

There is another very dangerous situation possible for customers that do load the success page in the end:
1. Customer confirmes order of e.g. €1.00 and gets redirected to the payment gateway.
2. Customer uses another tab in the browser to edit the order using the checkout with more products, e.g. €200.00
3. Customer completes the payment for the €1.00 amount, but the €200.00 order will be confirmed.
4. Payment gateway doesn't check the order amount paid compared to the order and order is confirmed. Remaining payment of €199.00 will probably only appear when doing tax administration and if Opencart orders are compared to actual paid amounts.

This is the most dangerous situation possible for which the customer can leave little trace of what happened:
1. Customer confirmes order of e.g. €1.00 and gets redirected to the payment gateway.
2. Customer completes the payment for the €1.00 amount and relies on the webhook of the payment gateway to complete the order.
3. Order is confirmed and all seems well. The order however is not instantly processed of course, only when the packing slip is actually printed. We presume it takes e.g. one hour for the processing to start.
4. As the order_id is never cleared in the session (no loading of success page), the customer can now use the checkout to overwrite the order with whatever they want, e.g. €200.00 of products.
5. The order is eventually processed and shipped using the new overwritten order data.
6. After you receive the shipped update, you can go back to the checkout and overwrite your order again, but then with the first €1.00 product. You will have paid €1.00, getting €200.00 of products, yet the system will contain data you only got a product worth of €1.00.

Since OC default will always create a new order_id for each confirmed order getting redirected to the payment gateway, this issue doesn't exist with any of the payment gateways using the OC default checkout.

I have verified all the above exploits. So far, they have not been exploited at our e-store, but we did have overwritten orders that were already confirmed, some times resulting in differences in order amount and type of product.

Please take note that the modification has only been tested on my own OC 3.0.3.7 + Journal 3.1.8 system with my payment gateways. While the modification is quite simple and universal, I advise to fully test each payment method to confirm this works for you. The OCMOD file contains some comments to explain what is done and why.

I hope this helps other users to get rid of this nasty problem in the Journal 3 Quick checkout. If you have another checkout solution with similar issues, you might be able to use (part of) the code to solve the issue.

Attachments


New member

Posts

Joined
Fri Feb 21, 2014 9:12 am

Post by JNeuhoff » Fri Aug 13, 2021 1:28 am

Thank you for looking into it. I assume the same issue exists for many other one-step checkout extensions?

Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig


User avatar
Guru Member

Posts

Joined
Wed Dec 05, 2007 3:38 am


Post by LVL91 » Wed Aug 18, 2021 10:33 pm

JNeuhoff wrote:
Fri Aug 13, 2021 1:28 am
Thank you for looking into it. I assume the same issue exists for many other one-step checkout extensions?
If these one-step checkout solutions use the order_id in the session as reference and create orders with order_status_id = 0 to save all the checkout data, then yes, they could very well have the same issues. The "Quick N Boosted" one-step checkout extension could be one of those as said in another post here.

New member

Posts

Joined
Fri Feb 21, 2014 9:12 am

Post by straightlight » Wed Aug 18, 2021 11:03 pm

Checking the last order ID created does not confirm that this last order ID belongs to the current guest / customer with this XML file.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by LVL91 » Tue Aug 31, 2021 9:01 am

straightlight wrote:
Wed Aug 18, 2021 11:03 pm
Checking the last order ID created does not confirm that this last order ID belongs to the current guest / customer with this XML file.
Thank you for the feedback straightlight, but that is not exactly what my OCMOD is doing. It mainly does these things only:
- Save the order_id that has been confirmed (and used by a payment method). It uses the session to save it.
- Check/compare the last confirmed order_id in the session (not THE last order_id, just the last confirmed order_id saved in the customers session)
- Check if the order_id being used exists in the database with order_status_id != '0' (not required actually, just extra safety)

This prevents all the nasty things for me. Also, I got confirmation from the Journal 3 developers that they will look into it and check if they can implement it for the next release. :)

New member

Posts

Joined
Fri Feb 21, 2014 9:12 am

Post by circustheshop » Tue Oct 26, 2021 5:59 pm

LVL91 wrote:
Fri Aug 13, 2021 1:19 am
This will probably be the last update for some time. The reply from the Journal 3 developers was not quite what I was expecting. Therefore I will explain what issues I had, explain the root cause with possible exploits involved and attach a OCMOD with fixes for these issues.

I had some issues with orders being overwritten, yet already confirmed, processed and shipped. As it turns out, the Quick checkout from Journal 3 has a major flaw. It uses the order_id in the session (if available) to update and confirm the order on the checkout page, but due to payment gateways, our customers will not always return to the success page. Webhooks usually take care of order confirmation, so quite some customers will simply do the payment, close the browser and never reach the success page. Due to this use case, the order_id never gets cleared in the session (by loading the success page) and the next time the checkout is used to edit anything in an order, it uses the exact same order_id to overwrite the entire order with the contents of the cart and other order data. There are no checks done for the order_id in the session being valid. This is extremely dangerous as customers will have a way of editing orders, even after they have been confirmed and paid. As a result stock levels don't match anymore and loss of money could be involved.

This issue doesn't exist (to some extend) as long as the customer will always follow the complete steps from checkout-->payment gateway-->success page as this will clear the order_id in the session. This is why you probably haven't heard from it much, also due to sessions expiring over time which also clears the session data.

There is another very dangerous situation possible for customers that do load the success page in the end:
1. Customer confirmes order of e.g. €1.00 and gets redirected to the payment gateway.
2. Customer uses another tab in the browser to edit the order using the checkout with more products, e.g. €200.00
3. Customer completes the payment for the €1.00 amount, but the €200.00 order will be confirmed.
4. Payment gateway doesn't check the order amount paid compared to the order and order is confirmed. Remaining payment of €199.00 will probably only appear when doing tax administration and if Opencart orders are compared to actual paid amounts.

This is the most dangerous situation possible for which the customer can leave little trace of what happened:
1. Customer confirmes order of e.g. €1.00 and gets redirected to the payment gateway.
2. Customer completes the payment for the €1.00 amount and relies on the webhook of the payment gateway to complete the order.
3. Order is confirmed and all seems well. The order however is not instantly processed of course, only when the packing slip is actually printed. We presume it takes e.g. one hour for the processing to start.
4. As the order_id is never cleared in the session (no loading of success page), the customer can now use the checkout to overwrite the order with whatever they want, e.g. €200.00 of products.
5. The order is eventually processed and shipped using the new overwritten order data.
6. After you receive the shipped update, you can go back to the checkout and overwrite your order again, but then with the first €1.00 product. You will have paid €1.00, getting €200.00 of products, yet the system will contain data you only got a product worth of €1.00.

Since OC default will always create a new order_id for each confirmed order getting redirected to the payment gateway, this issue doesn't exist with any of the payment gateways using the OC default checkout.

I have verified all the above exploits. So far, they have not been exploited at our e-store, but we did have overwritten orders that were already confirmed, some times resulting in differences in order amount and type of product.

Please take note that the modification has only been tested on my own OC 3.0.3.7 + Journal 3.1.8 system with my payment gateways. While the modification is quite simple and universal, I advise to fully test each payment method to confirm this works for you. The OCMOD file contains some comments to explain what is done and why.

I hope this helps other users to get rid of this nasty problem in the Journal 3 Quick checkout. If you have another checkout solution with similar issues, you might be able to use (part of) the code to solve the issue.
Hello good morning. I have the same problem, only with Opencart 3.0.3.2, would your solution work?
Can you tell me how to install it? I Copy your file directly to the System folder via FTP and refresh modifications, but in the modification console it does not appear.
Thanks!

Newbie

Posts

Joined
Tue Mar 12, 2019 8:15 pm

Post by isabad » Fri Feb 04, 2022 5:34 am

Hi ,
open catalog/model/journal3/order.php.
change line 168-173 to below code:

Code: Select all

/*if ($order_id) {
			$this->editOrder($order_id, $order_data);
		} else {
			$this->session->data['order_id'] = $this->addOrder($order_data);
		}*/
	
		$this->load->model('checkout/order');
		$order_info = $this->model_checkout_order->getOrder($order_id);
		if ($order_info) {
			// If order status is 0 then becomes greater than 0 send main html email
			if ($order_info['order_status_id'] > 0) {
				$this->session->data['order_id'] = $this->addOrder($order_data);
			} 
			
			// If order status is not 0 then send update text email
			if ($order_info['order_status_id'] == 0) {
				$this->editOrder($order_id, $order_data);
			}		
		}
and refresh modification.
______________________
https://www.opencart.com/index.php?rout ... n_id=42966

Newbie

Posts

Joined
Sun Feb 21, 2021 3:23 am
Who is online

Users browsing this forum: No registered users and 22 guests