Fix add protection to avoid bypass in paymentok

This commit is contained in:
Laurent Destailleur
2025-04-22 01:42:28 +02:00
parent 8b4561bc3c
commit 656a4f36e3
3 changed files with 52 additions and 23 deletions

View File

@@ -68,6 +68,7 @@ require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/eventorganization/class/conferenceorboothattendee.class.php';
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
require_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
@@ -132,7 +133,7 @@ if (!$action) {
$thirdparty = null; // Init for static analysis
$istrpecu = null; // Init for static analysis
$stripecu = null; // Init for static analysis
$paymentintent = null; // Init for static analysis
// Load data required later for actions and view
@@ -796,7 +797,7 @@ if ($action == 'charge' && isModEnabled('stripe')) { // Test on permission not r
$stripe = new Stripe($db);
$stripeacc = $stripe->getStripeAccount($service);
// We go here if $conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION is set.
// We go here if getDolGlobalString('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION') is set.
// In such a case, payment is always ok when we call the "charge" action.
$paymentintent_id = GETPOST("paymentintent_id", "alpha");
@@ -824,16 +825,23 @@ if ($action == 'charge' && isModEnabled('stripe')) { // Test on permission not r
dol_syslog($errormessage, LOG_WARNING, 0, '_payment');
setEventMessages($paymentintent->status, null, 'errors');
$action = '';
$randomseckey = getRandomPassword(true, null, 20);
$_SESSION['paymentkosessionkey'] = $randomseckey; // key between newpayment.php to paymentko.php
$urlko .= '&paymentkosessionkey='.urlencode($randomseckey);
} else {
// TODO We can also record the payment mode into llx_societe_rib with stripe $paymentintent->payment_method
// We can also record the payment mode into llx_societe_rib with stripe $paymentintent->payment_method
// Note that with other old Stripe architecture (using Charge API), the payment mode was not recorded, so it is not mandatory to do it here.
//dol_syslog("Create payment_method for ".$paymentintent->payment_method, LOG_DEBUG, 0, '_payment');
// dol_syslog("Create payment_method for ".$paymentintent->payment_method, LOG_DEBUG, 0, '_payment');
// Get here amount and currency used for payment and force value into $amount and $currency so the real amount is saved into session instead
// of the amount and currency retrieved from the POST.
if (!empty($paymentintent->currency) && !empty($paymentintent->amount)) {
$amount = $paymentintent->amount;
$currency = '';
if (!empty($paymentintent->currency)) {
$currency = strtoupper($paymentintent->currency);
$amount = $paymentintent->amount;
// Correct the amount according to unit of currency
// See https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support
@@ -842,6 +850,13 @@ if ($action == 'charge' && isModEnabled('stripe')) { // Test on permission not r
$amount /= 100;
}
}
dol_syslog("StatusOfRetrievedIntent is succeeded for amount = ".$amount." currency = ".$currency, LOG_DEBUG, 0, '_payment');
$randomseckey = getRandomPassword(true, null, 20);
$_SESSION['paymentoksessionkey'] = $randomseckey; // key between newpayment.php to paymentok.php
$urlok .= '&paymentoksessionkey='.urlencode($randomseckey);
}
}
@@ -858,7 +873,8 @@ if ($action == 'charge' && isModEnabled('stripe')) { // Test on permission not r
$_SESSION['errormessage'] = $errormessage;
dol_syslog("Action charge stripe STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION=".getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION')." ip=".$remoteip, LOG_DEBUG, 0, '_payment');
dol_syslog("onlinetoken=".$_SESSION["onlinetoken"]." FinalPaymentAmt=".$_SESSION["FinalPaymentAmt"]." currencyCodeType=".$_SESSION["currencyCodeType"]." payerID=".$_SESSION['payerID']." TRANSACTIONID=".$_SESSION['TRANSACTIONID'], LOG_DEBUG, 0, '_payment');
dol_syslog("onlinetoken=".$_SESSION["onlinetoken"]." paymentsessionkey=".$_SESSION["paymentsessionkey"], LOG_DEBUG, 0, '_payment');
dol_syslog("FinalPaymentAmt=".$_SESSION["FinalPaymentAmt"]." currencyCodeType=".$_SESSION["currencyCodeType"]." payerID=".$_SESSION['payerID']." TRANSACTIONID=".$_SESSION['TRANSACTIONID'], LOG_DEBUG, 0, '_payment');
dol_syslog("FULLTAG=".$FULLTAG, LOG_DEBUG, 0, '_payment');
dol_syslog("error=".$error." errormessage=".$errormessage, LOG_DEBUG, 0, '_payment');
dol_syslog("_SERVER[SERVER_NAME] = ".(empty($_SERVER["SERVER_NAME"]) ? '' : dol_escape_htmltag($_SERVER["SERVER_NAME"])), LOG_DEBUG, 0, '_payment');

View File

@@ -163,7 +163,6 @@ if ($ws) {
// None
/*
* View
*/
@@ -178,6 +177,7 @@ foreach ($_POST as $k => $v) {
}
dol_syslog("POST=".$tracepost, LOG_DEBUG, 0, '_payment');
dol_syslog("paymentkosessionkey=".GETPOST('paymentkosessionkey')." SESSION['paymentkosessionkey']=".$_SESSION['paymentkosessionkey'], LOG_DEBUG, 0, '_payment');
// Set $appli for emails title
$appli = $mysoc->name;
@@ -348,15 +348,15 @@ $db->close();
// If option to do a redirect somewhere else is defined.
if (!empty($doactionsthenredirect)) {
$randomseckey = getRandomPassword(true, null, 20);
$_SESSION['paymentsessionkey'] = $randomseckey;
// Redirect to an error page
$randomseckey = getRandomPassword(true, null, 20);
$_SESSION['paymentkosessionkey'] = $randomseckey; // key between paymentok.php to another page like a paymentko of the website.
// Paymentko page must be created for the specific website
if (!defined('USEDOLIBARRSERVER') && !empty($ws_virtuelhost)) {
$ext_urlko = $ws_virtuelhost . '/paymentko.php?paymentsessionkey='.urlencode($randomseckey).'&fulltag='.$FULLTAG;
$ext_urlko = $ws_virtuelhost . '/paymentko.php?paymentkosessionkey='.urlencode($randomseckey).'&fulltag='.$FULLTAG;
} else {
$ext_urlko = DOL_URL_ROOT.'/public/website/index.php?paymentsessionkey='.urlencode($randomseckey).'&website='.urlencode($ws).'&pageref=paymentko&fulltag='.$FULLTAG;
$ext_urlko = DOL_URL_ROOT.'/public/website/index.php?paymentkosessionkey='.urlencode($randomseckey).'&website='.urlencode($ws).'&pageref=paymentko&fulltag='.$FULLTAG;
}
dol_syslog("Now do a redirect using Location : ".$ext_urlko, LOG_DEBUG, 0, '_payment');

View File

@@ -181,9 +181,15 @@ if ($ws) {
}
}
/*
* Actions
*/
// None
/*
* Actions and view
* View
*/
$now = dol_now();
@@ -199,14 +205,17 @@ foreach ($_POST as $k => $v) {
}
}
dol_syslog("POST=".$tracepost, LOG_DEBUG, 0, '_payment');
$tracesession = "";
foreach ($_SESSION as $k => $v) {
if (is_scalar($k) && is_scalar($v)) {
if (is_scalar($k) && is_scalar($v) && in_array($k, array('currencyCodeType', 'errormessage', 'FinalPaymentAmt', 'ipaddress', 'onlinetoken', 'payerID', 'paymentType', 'TRANSACTIONID', 'paymentoksessionkey', 'paymentkosessionkey'))) {
$tracesession .= "$k - $v\n";
}
}
dol_syslog("SESSION=".$tracesession, LOG_DEBUG, 0, '_payment');
dol_syslog("paymentoksessionkey=".GETPOST('paymentoksessionkey')." SESSION['paymentoksessionkey']=".$_SESSION['paymentoksessionkey'], LOG_DEBUG, 0, '_payment');
$head = '';
if (getDolGlobalString('ONLINE_PAYMENT_CSS_URL')) {
$head = '<link rel="stylesheet" type="text/css" href="' . getDolGlobalString('ONLINE_PAYMENT_CSS_URL').'?lang='.$langs->defaultlang.'">'."\n";
@@ -370,7 +379,8 @@ if (isModEnabled('paybox')) {
// For Stripe
if (isModEnabled('stripe')) {
if ($paymentmethod === 'stripe') {
// TODO Add a check to validate that payment is ok. We can request Stripe with payment_intent and payment_intent_client_secret
// TODO Add a check to validate that payment is ok.
// We can request Stripe with payment_intent and payment_intent_client_secret the sameway we do in newpayment after comment "// Get here amount and currency used for payment".
$ispaymentok = true; // We call this page only if payment is ok on payment system
}
}
@@ -2162,16 +2172,16 @@ $db->close();
// If option to do a redirect somewhere else.
if (!empty($doactionsthenredirect)) {
$randomseckey = getRandomPassword(true, null, 20);
$_SESSION['paymentsessionkey'] = $randomseckey;
if ($ispaymentok) {
// Redirect to a success page
$randomseckey = getRandomPassword(true, null, 20);
$_SESSION['paymentoksessionkey'] = $randomseckey; // key between paymentok.php to another page like a paymentok of the website.
// Paymentok page must be created for the specific website
if (!defined('USEDOLIBARRSERVER') && !empty($ws_virtuelhost)) {
$ext_urlok = $ws_virtuelhost . '/paymentok.php?paymentsessionkey='.urlencode($randomseckey).'&fulltag='.$FULLTAG;
$ext_urlok = $ws_virtuelhost . '/paymentok.php?paymentoksessionkey='.urlencode($randomseckey).'&fulltag='.$FULLTAG;
} else {
$ext_urlok = DOL_URL_ROOT.'/public/website/index.php?paymentsessionkey='.urlencode($randomseckey).'&website='.urlencode($ws).'&pageref=paymentok&fulltag='.$FULLTAG;
$ext_urlok = DOL_URL_ROOT.'/public/website/index.php?paymentoksessionkey='.urlencode($randomseckey).'&website='.urlencode($ws).'&pageref=paymentok&fulltag='.$FULLTAG;
}
dol_syslog("Now do a redirect using a Location: ".$ext_urlok, LOG_DEBUG, 0, '_payment');
@@ -2179,11 +2189,14 @@ if (!empty($doactionsthenredirect)) {
exit;
} else {
// Redirect to an error page
$randomseckey = getRandomPassword(true, null, 20);
$_SESSION['paymentkosessionkey'] = $randomseckey; // key between paymentok.php to another page like a paymentko of the website.
// Paymentko page must be created for the specific website
if (!defined('USEDOLIBARRSERVER') && !empty($ws_virtuelhost)) {
$ext_urlko = $ws_virtuelhost . '/paymentko.php?paymentsessionkey='.urlencode($randomseckey).'&fulltag='.$FULLTAG;
$ext_urlko = $ws_virtuelhost . '/paymentko.php?paymentkosessionkey='.urlencode($randomseckey).'&fulltag='.$FULLTAG;
} else {
$ext_urlko = DOL_URL_ROOT.'/public/website/index.php?paymentsessionkey='.urlencode($randomseckey).'&website='.urlencode($ws).'&pageref=paymentko&fulltag='.$FULLTAG;
$ext_urlko = DOL_URL_ROOT.'/public/website/index.php?paymentkosessionkey='.urlencode($randomseckey).'&website='.urlencode($ws).'&pageref=paymentko&fulltag='.$FULLTAG;
}
dol_syslog("Now do a redirect using a Location:".$ext_urlko, LOG_DEBUG, 0, '_payment');