Headline
CVE-2022-29254: [CVE-2022-29254] Add extra validation on payment completion · silverstripe/silverstripe-omnipay@7dee9a1
silverstripe-omnipay is a SilverStripe integration with Omnipay PHP payments library. For a subset of Omnipay gateways (those that use intermediary states like isNotification()
or isRedirect()
), if the payment identifier or success URL is exposed it is possible for payments to be prematurely marked as completed without payment being taken. This is mitigated by the fact that most payment gateways hide this information from users, however some issuing banks offer flawed 3DSecure implementations that may inadvertently expose this data. The following versions have been patched to fix this issue: 2.5.2
, 3.0.2
, 3.1.4
, and 3.2.1
. There are no known workarounds for this vulnerability.
@@ -3,14 +3,19 @@ namespace SilverStripe\Omnipay\Service;
use Omnipay\Common\Message\RequestInterface; use SilverStripe\Omnipay\Exception\InvalidStateException; use SilverStripe\Omnipay\Exception\InvalidConfigurationException; use SilverStripe\Omnipay\Exception\InvalidStateException; use SilverStripe\Omnipay\Helper\ErrorHandling; use SilverStripe\Omnipay\Model\Message; use SilverStripe\Omnipay\Model\Message\AwaitingCreateCardResponse; use SilverStripe\Omnipay\Model\Message\CompleteCreateCardError; use SilverStripe\Omnipay\Model\Message\CompleteCreateCardRequest; use SilverStripe\Omnipay\Model\Message\CreateCardError; use SilverStripe\Omnipay\Model\Message\CreateCardRedirectResponse; use SilverStripe\Omnipay\Model\Message\CreateCardRequest; use SilverStripe\Omnipay\Model\Message\CreateCardResponse;
class CreateCardService extends PaymentService {
/** * Start a createcard request * @@ -39,12 +44,12 @@ public function initiate($data = array()) $request = $this->oGateway()->createCard($gatewayData); $this->extend('onAfterCreateCard’, $request);
$this->createMessage(Message\CreateCardRequest::class, $request); $this->createMessage(CreateCardRequest::class, $request);
try { $response = $this->response = $request->send(); } catch (\Omnipay\Common\Exception\OmnipayException $e) { $this->createMessage(Message\CreateCardError::class, $e); $this->createMessage(CreateCardError::class, $e); // create an error response return $this->generateServiceResponse(ServiceResponse::SERVICE_ERROR); } @@ -58,12 +63,12 @@ public function initiate($data = array()) $this->payment->write();
$this->createMessage( $serviceResponse->isRedirect() ? Message\CreateCardRedirectResponse::class : Message\AwaitingCreateCardResponse::class, $serviceResponse->isRedirect() ? CreateCardRedirectResponse::class : AwaitingCreateCardResponse::class, $response ); } elseif ($serviceResponse->isError()) { $this->createMessage(Message\CreateCardError::class, $response); } else { $this->createMessage(CreateCardError::class, $response); } elseif ($serviceResponse->isSuccessful()) { $this->markCompleted('CardCreated’, $serviceResponse, $response); }
@@ -103,26 +108,23 @@ public function complete($data = array(), $isNotification = false) $request = $gateway->completeCreateCard($gatewayData); $this->extend('onAfterCompleteCreateCard’, $request);
$this->createMessage(Message\CompleteCreateCardRequest::class, $request); $this->createMessage(CompleteCreateCardRequest::class, $request); $response = null; try { $response = $this->response = $request->send(); } catch (\Omnipay\Common\Exception\OmnipayException $e) { $this->createMessage(Message\CompleteCreateCardError::class, $e); $this->createMessage(CompleteCreateCardError::class, $e); return $this->generateServiceResponse($flags | ServiceResponse::SERVICE_ERROR); }
$serviceResponse = $this->wrapOmnipayResponse($response, $isNotification);
if ($serviceResponse->isError()) { $this->createMessage(Message\CompleteCreateCardError::class, $response); return $serviceResponse; }
if (!$serviceResponse->isAwaitingNotification()) { $this->markCompleted('CardCreated’, $serviceResponse, $response); } else { if ($serviceResponse->isAwaitingNotification()) { ErrorHandling::safeExtend($this->payment, 'onAwaitingCreateCard’, $serviceResponse); } elseif ($serviceResponse->isError()) { $this->createMessage(CompleteCreateCardError::class, $response); } elseif ($serviceResponse->isSuccessful()) { $this->markCompleted('CardCreated’, $serviceResponse, $response); }
return $serviceResponse; @@ -131,7 +133,7 @@ public function complete($data = array(), $isNotification = false) protected function markCompleted($endStatus, ServiceResponse $serviceResponse, $gatewayMessage) { parent::markCompleted($endStatus, $serviceResponse, $gatewayMessage); $this->createMessage(Message\CreateCardResponse::class, $gatewayMessage); $this->createMessage(CreateCardResponse::class, $gatewayMessage); ErrorHandling::safeExtend($this->payment, 'onCardCreated’, $serviceResponse); } }
Related news
Silverstripe silverstripe/assets through 1.10 allows XSS.
### Impact For a subset of Omnipay gateways (those that use intermediary states like `isNotification()` or `isRedirect()`), if the payment identifier or success URL is exposed it is possible for payments to be prematurely marked as completed without payment being taken. This is mitigated by the fact that most payment gateways hide this information from users, however some issuing banks offer flawed 3DSecure implementations that may inadvertently expose this data. ### Patches The following versions have been patched to fix this issue: - `2.5.2` - `3.0.2` - `3.1.4` - `3.2.1` ### Workarounds There are no known workarounds for this vulnerability. ### References N/A. ### For more information If you have any questions or comments about this advisory: * Email us at [[email protected]](mailto:[email protected])