Hi,
I have found a "bug" in pages that redirect to checkout_payment page.
I use Apache 2.x on Ubuntu and Debian. The Ubuntu system is used for development and The Apache 2.x on that one has Suhosin patch by default.
I have a web POS module for Turkish banks. The code's message dispatching is derived from other payment modules
Some lines such as causes the HTTPO 406 error.
Code:
$payment_error_return = "payment_error=".$this->code."&error=".urlencode( $error )."&webpos_cc_owner=".urlencode( $_POST['webpos_cc_owner'] )."&webpos_cc_expires_month=".$_POST['webpos_cc_expires_month']."&webpos_cc_expires_year=".$_POST['webpos_cc_expires_year']."&webpos_cc_checkcode=".$_POST['webpos_cc_checkcode'];
zen_redirect( zen_href_link( FILENAME_CHECKOUT_PAYMENT, $payment_error_return, "SSL", true, false ) );
As seen from the code the error message is dispatched to the checkout_payment page as very long GET parameters.
The result of an error should be shown on the header of that page, but we get a blank page instead.
I have got strict error reporting and error reportinh patch turned on. There is no message in the error log...
Therefore I issued the command tail -f /var/log/apache2/*.log
The apache log shows 406 responses.
Doing a quick investigation shows that sending very long GET requests is blocked by mod_security and Suhosin patch.
There are two solutions for this incidence:
1-Disable mod_security
a) For all the sites you have (CAN BE VERY DANGEROUS !)
b) Use that code for your .htaccess onb your site:
Code:
<IfModule mod_security.c>
SecFilterEngine Off
SecFilterScanPOST Off
SecFilterInheritance Off
</IfModule>
This CAN BE DANGEROUS and DOES HAVE NO EFFECT if you have the Suhosin patch.
2-The safest solution follows:
a- Alter payment pages not to send GET redirects and store messages in the $_SESSION global var,
and
b- Alter checkout_payment page's header.php to handle the messages set in the payment pages
To do this I have changed the code for my payment module code from:
Code:
$payment_error_return = "payment_error=".$this->code."&error=".urlencode( $error )."&webpos_cc_owner=".urlencode( $_POST['webpos_cc_owner'] )."&webpos_cc_expires_month=".$_POST['webpos_cc_expires_month']."&webpos_cc_expires_year=".$_POST['webpos_cc_expires_year']."&webpos_cc_checkcode=".$_POST['webpos_cc_checkcode'];
zen_redirect( zen_href_link( FILENAME_CHECKOUT_PAYMENT, $payment_error_return, "SSL", true, false ) );
to:
Code:
$_SESSION['webpos']['payment_error']=urlencode( $error );
zen_redirect( zen_href_link( FILENAME_CHECKOUT_PAYMENT, "", "SSL", true, false ) );
There WOULD BE many lines that send GET requests and redirects, therefore you would have to change all of them.
To handle and show the messages I changed the code in the file includes/modules/pages/checkout_payment/header_php.php
from:
Code:
if (isset($_GET['payment_error']) && is_object(${$_GET['payment_error']}) && ($error = ${$_GET['payment_error']}->get_error())) {
$messageStack->add('checkout_payment', $error['error'], 'error');
}
to:
Code:
if (isset($_GET['payment_error']) && is_object(${$_GET['payment_error']}) && ($error = ${$_GET['payment_error']}->get_error())) {
$messageStack->add('checkout_payment', $error['error'], 'error');
}
if( isset($_SESSION['webpos']['payment_error']) ){
$messageStack->add('checkout_payment', urldecode($_SESSION['webpos']['payment_error']), 'error');
unset($_SESSION['webpos']['payment_error']);
}
This solves the problem in the most secure way without any GET requests.
I hope this contribution is helpful.
More questions ? Please do as them ;)
Best of luck,
Koray
Bookmarks