Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/salesmanago/salesmanago.php
+++ b/salesmanago/salesmanago.php
@@ -3,7 +3,7 @@
* Plugin Name: SALESmanago & Leadoo
* Plugin URI: https://www.salesmanago.com/?utm_source=integration&utm_medium=WORDPRESS&utm_content=marketplace
* Description: SALESmanago Marketing Automation integration for WordPress, WooCommerce, Contact Form 7, Gravity Forms, Tier Pricing
- * Version: 3.11.2
+ * Version: 3.11.3
* Tested up to: 6.9.4
* Requires PHP: 7.4
* Author: SALESmanago
@@ -65,6 +65,3 @@
}
add_action('plugins_loaded', 'main_salesmanago');
-
-
-
--- a/salesmanago/src/Admin/Controller/ExportController.php
+++ b/salesmanago/src/Admin/Controller/ExportController.php
@@ -50,7 +50,7 @@
$this->SMExportController = new SMExportController( $this->AdminModel->getConfiguration() );
$this->registerActions();
} catch ( Exception $e ) {
- $this->ExportModel->setMessage( $e->getMessage() );
+ $this->ExportModel->setMessage( $this->sanitize_error_message( $e->getMessage() ) );
$this->ExportModel->setStatus( self::FAILED );
$this->ExportModel->buildResponse();
}
@@ -70,37 +70,54 @@
}
/**
- *
+ * Count contacts for export
*/
public function countContacts() {
try {
- SecureHelper::validate_ajax_nonce( 'salesmanago_export_count_contacts' );
+ SecureHelper::validate_ajax_nonce( 'salesmanago_export_count_contacts' );
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ $this->ExportModel->setMessage( 'Access denied' );
+ $this->ExportModel->setStatus( self::FAILED );
+ $this->ExportModel->buildResponse();
+ return;
+ }
$this->ExportModel->parseArgs();
$this->ExportModel->setExportType( self::CONTACTS );
$query = $this->ExportModel->getExportContactsQuery( true );
+ if ( ! $query ) {
+ throw new Exception( 'Failed to generate contacts query' );
+ }
$this->ExportModel->setCount( $this->db->get_var( $query ) );
$this->ExportModel->setPackageCount( (int) ceil( $this->ExportModel->getCount() / ExportModel::PACKAGE_SIZE ) );
$this->ExportModel->setStatus( self::PREPARING );
$this->ExportModel->buildResponse();
} catch ( Exception $e ) {
- $this->ExportModel->setMessage( $e->getViewMessage() );
+ $this->ExportModel->setMessage( $this->sanitize_error_message( method_exists( $e, 'getViewMessage' ) ? $e->getViewMessage() : $e->getMessage() ) );
$this->ExportModel->setStatus( self::FAILED );
$this->ExportModel->buildResponse();
} catch ( Exception $e ) {
- $this->ExportModel->setMessage( $e->getMessage() );
+ $this->ExportModel->setMessage( $this->sanitize_error_message( $e->getMessage() ) );
$this->ExportModel->setStatus( self::FAILED );
$this->ExportModel->buildResponse();
}
}
/**
- *
+ * Count events for export
*/
public function countEvents() {
try {
- SecureHelper::validate_ajax_nonce( 'salesmanago_export_count_events' );
+ SecureHelper::validate_ajax_nonce( 'salesmanago_export_count_events' );
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ $this->ExportModel->setMessage( 'Access denied' );
+ $this->ExportModel->setStatus( self::FAILED );
+ $this->ExportModel->buildResponse();
+ return;
+ }
$this->ExportModel->parseArgs();
$this->ExportModel->setExportType( self::EVENTS );
@@ -110,17 +127,24 @@
$this->ExportModel->setStatus( self::PREPARING );
$this->ExportModel->buildResponse();
} catch ( Exception $e ) {
- $this->ExportModel->setMessage( $e->getMessage() );
+ $this->ExportModel->setMessage( $this->sanitize_error_message( $e->getMessage() ) );
$this->ExportModel->setStatus( self::FAILED );
$this->ExportModel->buildResponse();
}
}
/**
- *
+ * Export contacts batch
*/
public function exportContacts() {
- SecureHelper::validate_ajax_nonce( 'salesmanago_count_contacts' );
+ SecureHelper::validate_ajax_nonce( 'salesmanago_export_contacts' );
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ $this->ExportModel->setMessage( 'Access denied' );
+ $this->ExportModel->setStatus( self::FAILED );
+ $this->ExportModel->buildResponse();
+ return;
+ }
$this->ExportModel->parseArgs();
if ( $this->ExportModel->getPackageCount() ) {
@@ -128,19 +152,21 @@
$this->ExportModel->setExportType( self::CONTACTS );
$query = $this->ExportModel->getExportContactsQuery( false );
+ if ( ! $query ) {
+ throw new Exception( 'Failed to generate export query' );
+ }
$results = $this->db->get_results( $query, ARRAY_A );
if ( ! empty( $results ) ) {
$Collection = $this->ExportModel->prepareContactsToExport( $results );
- if ( ! $Collection->isEmpty() ) {
+ if ( $Collection && ! $Collection->isEmpty() ) {
$exportResponse = $this->SMExportController->export( $Collection );
- if ( $exportResponse->getStatus() ) {
+ if ( $exportResponse && $exportResponse->getStatus() ) {
$this->ExportModel->setLastExportedPackage(
$this->ExportModel->getLastExportedPackage() + 1
);
- if ( $this->ExportModel->getLastExportedPackage() + 1 == $this->ExportModel->getPackageCount(
- ) ) {
+ if ( $this->ExportModel->getLastExportedPackage() + 1 == $this->ExportModel->getPackageCount() ) {
$this->ExportModel->setStatus( self::LAST_CHECK );
$this->ExportModel->buildResponse();
} else {
@@ -161,11 +187,11 @@
$this->ExportModel->buildResponse();
}
} catch ( Exception $e ) {
- $this->ExportModel->setMessage( $e->getViewMessage() );
+ $this->ExportModel->setMessage( $this->sanitize_error_message( method_exists( $e, 'getViewMessage' ) ? $e->getViewMessage() : $e->getMessage() ) );
$this->ExportModel->setStatus( self::FAILED );
$this->ExportModel->buildResponse();
} catch ( Exception $e ) {
- $this->ExportModel->setMessage( $e->getMessage() );
+ $this->ExportModel->setMessage( $this->sanitize_error_message( $e->getMessage() ) );
$this->ExportModel->setStatus( self::FAILED );
$this->ExportModel->buildResponse();
}
@@ -177,10 +203,17 @@
}
/**
- *
+ * Export events batch
*/
public function exportEvents() {
- SecureHelper::validate_ajax_nonce( 'salesmanago_export_events' );
+ SecureHelper::validate_ajax_nonce( 'salesmanago_export_events' );
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ $this->ExportModel->setMessage( 'Access denied' );
+ $this->ExportModel->setStatus( self::FAILED );
+ $this->ExportModel->buildResponse();
+ return;
+ }
$this->ExportModel->parseArgs();
if ( $this->ExportModel->getPackageCount() ) {
@@ -193,7 +226,7 @@
$Collection = $this->ExportModel->prepareEventsToExport( $results );
$exportResponse = $this->SMExportController->export( $Collection );
- if ( $exportResponse->getStatus() ) {
+ if ( $exportResponse && $exportResponse->getStatus() ) {
$this->ExportModel->setLastExportedPackage( $this->ExportModel->getLastExportedPackage() + 1 );
if ( $this->ExportModel->getLastExportedPackage() + 1 == $this->ExportModel->getPackageCount() ) {
$this->ExportModel->setStatus( self::LAST_CHECK );
@@ -212,11 +245,11 @@
$this->ExportModel->buildResponse();
}
} catch ( Exception $e ) {
- $this->ExportModel->setMessage( $e->getViewMessage() );
+ $this->ExportModel->setMessage( $this->sanitize_error_message( method_exists( $e, 'getViewMessage' ) ? $e->getViewMessage() : $e->getMessage() ) );
$this->ExportModel->setStatus( self::FAILED );
$this->ExportModel->buildResponse();
} catch ( Exception $e ) {
- $this->ExportModel->setMessage( $e->getMessage() );
+ $this->ExportModel->setMessage( $this->sanitize_error_message( $e->getMessage() ) );
$this->ExportModel->setStatus( self::FAILED );
$this->ExportModel->buildResponse();
}
@@ -231,10 +264,18 @@
* Handle export products request
*/
public function exportProducts() {
- SecureHelper::validate_ajax_nonce( 'salesmanago_export_products' );
+ SecureHelper::validate_ajax_nonce( 'salesmanago_export_products' );
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ $this->ExportModel->setMessage( 'Access denied' );
+ $this->ExportModel->setStatus( self::FAILED );
+ $this->ExportModel->buildProductExportResponse();
+ return;
+ }
if ( ! $this->AdminModel->getConfiguration()->getApiV3Key() ) {
$this->ExportModel->buildProductExportResponseForExpiredApiKey();
+ return;
}
try {
$this->ExportModel->parseProductExportArgs();
@@ -251,15 +292,14 @@
$this->ExportModel->handlePackageCount();
} catch ( Exception $e ) {
$this->ExportModel->setStatus( self::FAILED );
- $this->ExportModel->setMessage( $e->getMessage() );
+ $this->ExportModel->setMessage( $this->sanitize_error_message( $e->getMessage() ) );
if ( $e instanceof ApiV3Exception ) {
$arr_of_messages = $e->getAllViewMessages();
- if ( IncludesHelper::extract_product_id_from_error_message_array( $arr_of_messages, $ProductsCollection ) ) {
- $this->ExportModel->setMessage(
- IncludesHelper::extract_product_id_from_error_message_array( $arr_of_messages, $ProductsCollection )
- );
+ $extracted_msg = IncludesHelper::extract_product_id_from_error_message_array( $arr_of_messages, $ProductsCollection ?? null );
+ if ( $extracted_msg ) {
+ $this->ExportModel->setMessage( $this->sanitize_error_message( $extracted_msg ) );
} else {
- $this->ExportModel->setMessage( $e->getViewMessage() );
+ $this->ExportModel->setMessage( $this->sanitize_error_message( method_exists( $e, 'getViewMessage' ) ? $e->getViewMessage() : $e->getMessage() ) );
}
if ( in_array( 10, $e->getCodes() ) ) {
$this->AdminModel->getConfiguration()->setApiV3Key( '' );
@@ -270,4 +310,27 @@
$this->ExportModel->buildProductExportResponse();
}
}
+
+ /**
+ * Sanitize error messages to prevent XSS and log injection
+ *
+ * @param string $message Raw error message
+ * @return string Sanitized message safe for output/logging
+ */
+ private function sanitize_error_message( $message ) {
+ if ( ! is_string( $message ) ) {
+ return '';
+ }
+
+ $sanitized = preg_replace( '/[rntx00-x1Fx7F]/', ' ', $message );
+
+ // Trim and limit length to prevent log flooding/DoS
+ $sanitized = substr( trim( $sanitized ), 0, 1024 );
+
+ if ( function_exists( 'esc_html' ) ) {
+ $sanitized = esc_html( $sanitized );
+ }
+
+ return $sanitized;
+ }
}
--- a/salesmanago/src/Admin/Entity/MessageEntity.php
+++ b/salesmanago/src/Admin/Entity/MessageEntity.php
@@ -42,13 +42,12 @@
public function addException($e, $type='error')
{
$this->messages[] = array(
- 'type' => $type,
- 'message' => $e->getMessage(),
- 'code' => $e->getCode()
+ 'type' => $this->sanitize_type( $type ),
+ 'message' => $this->sanitize_message( $e->getMessage() ),
+ 'code' => $this->sanitize_code( $e->getCode() )
);
}
-
/**
* @param string $message
* @param string $type
@@ -60,9 +59,9 @@
$code = 700;
}
$this->messages[] = array(
- 'type' => $type,
- 'message' => $message,
- 'code' => $code
+ 'type' => $this->sanitize_type( $type ),
+ 'message' => $this->sanitize_message( $message ),
+ 'code' => $this->sanitize_code( $code )
);
}
@@ -124,7 +123,6 @@
681 => __('Error on listing Fluent Forms', 'salesmanago'),
690 => __('Error on Monitoring code page', 'salesmanago'),
-
700 => __('Success.', 'salesmanago'),
701 => __('Logged in.', 'salesmanago'),
702 => __('Logged out.', 'salesmanago'),
@@ -132,13 +130,13 @@
// APIv3 Product Catalog Messages
704 => __( 'Authentication successful. You can select an existing Product Catalog or create a new one.', 'salesmanago' ),
- 705 => __( 'The API key doesn’t seem valid. Make sure the key is active and all characters have been copied.', 'salesmanago' ),
+ 705 => __( 'The API key doesn't seem valid. Make sure the key is active and all characters have been copied.', 'salesmanago' ),
706 => __( 'Unknown API error.', 'salesmanago' ),
- 707 => __( 'New Product Catalog has been created. Please refresh Catalog list to use it.', 'salesmanago' ),
- 708 => __( 'Incorrect location field value. Please check it in the Integration settings tab', 'salesmanago' ),
- 709 => __( 'Error on setting the active catalog', 'salesmanago' ),
- 710 => __( 'The request has timed out. Please try again', 'salesmanago' ),
- 711 => __( 'Product Catalog has not been created. Please check the About tab for error information.', 'salesmanago' )
+ 707 => __( 'New Product Catalog has been created. Please refresh Catalog list to use it.', 'salesmanago' ),
+ 708 => __( 'Incorrect location field value. Please check it in the Integration settings tab', 'salesmanago' ),
+ 709 => __( 'Error on setting the active catalog', 'salesmanago' ),
+ 710 => __( 'The request has timed out. Please try again', 'salesmanago' ),
+ 711 => __( 'Product Catalog has not been created. Please check the About tab for error information.', 'salesmanago' )
);
if(!isset($messages[$code]) && isset($messages[floor($code/10)*10])) {
$code = floor($code/10)*10;
@@ -147,7 +145,8 @@
} elseif (!isset($messages[$code])) {
$code = 0;
}
- return ($appendConsoleInfo) ? $messages[$code].$checkConsole : $messages[$code];
+ $message = isset($messages[$code]) ? esc_html( $messages[$code] ) : esc_html( $messages[0] );
+ return ($appendConsoleInfo) ? $message . $checkConsole : $message;
}
/**
@@ -160,18 +159,16 @@
if( empty( $message['type'] ) ) {
continue;
}
+ $type = esc_attr( $this->sanitize_type( $message['type'] ) );
+
if( $message['type'] === 'error' || $message['type'] === 'warning' ) {
$viewMessage = $this->getMessageByCode( $message['code'], true );
- $consoleMessage = str_replace("'", '\'',
- str_replace( "n", '\n', $message['message'] ) );
- $type = empty( $message['type'] ) ? 'info' : $message['type'];
-
+ $consoleMessage = wp_json_encode( $message['message'] );
+
$out .= '<div class="salesmanago-notice notice notice-' . $type . ' inline">' . $viewMessage . '</div>';
- $out .= '<script>console.warn('SM error '. $message['code'] . ': ' . $consoleMessage . '')</script>';
+ $out .= '<script>console.warn("SM error ' . esc_js( $message['code'] ) . ': " + ' . $consoleMessage . ')</script>';
} elseif ( $message['type'] === 'success' || $message['type'] === 'info' ) {
$viewMessage = $this->getMessageByCode( $message['code'], false );
- $type = empty( $message['type'] ) ? 'info' : $message['type'];
-
$out .= '<div class="salesmanago-notice notice notice-' . $type . ' inline">' . $viewMessage . '</div>';
} elseif ( $message['type'] === 'apiV3Error' ) {
$viewMessage = $this->getMessageByCode( $message['code'], false );
@@ -183,10 +180,23 @@
/**
* @param mixed $messages
+ * @return $this
*/
public function setMessages($messages)
{
- $this->messages = $messages;
+ if ( is_array( $messages ) ) {
+ $sanitized = array();
+ foreach ( $messages as $msg ) {
+ if ( is_array( $msg ) && isset( $msg['type'], $msg['message'], $msg['code'] ) ) {
+ $sanitized[] = array(
+ 'type' => $this->sanitize_type( $msg['type'] ),
+ 'message' => $this->sanitize_message( $msg['message'] ),
+ 'code' => $this->sanitize_code( $msg['code'] ),
+ );
+ }
+ }
+ $this->messages = $sanitized;
+ }
return $this;
}
@@ -200,10 +210,51 @@
/**
* @param bool $messagesAfterView
+ * @return $this
*/
public function setMessagesAfterView($messagesAfterView)
{
- $this->messagesAfterView = $messagesAfterView;
+ $this->messagesAfterView = (bool) $messagesAfterView;
return $this;
}
+
+ // ========================================================================
+ // SECURITY HELPER METHODS (for sanitization/escaping)
+ // ========================================================================
+
+ /**
+ * Sanitize message type to allowed values only
+ *
+ * @param string $type
+ * @return string
+ */
+ private function sanitize_type( $type ) {
+ $allowed = array( 'error', 'warning', 'success', 'info', 'apiV3Error' );
+ return in_array( $type, $allowed, true ) ? $type : 'info';
+ }
+
+ /**
+ * Sanitize message text to prevent XSS and log injection
+ *
+ * @param string $message
+ * @return string
+ */
+ private function sanitize_message( $message ) {
+ if ( ! is_string( $message ) ) {
+ return '';
+ }
+ $sanitized = preg_replace( '/[rntx00-x1Fx7F]/', ' ', $message );
+ // Trim and limit length to prevent log flooding/DoS
+ return substr( trim( $sanitized ), 0, 2048 );
+ }
+
+ /**
+ * Sanitize message code to integer
+ *
+ * @param mixed $code
+ * @return int
+ */
+ private function sanitize_code( $code ) {
+ return filter_var( $code, FILTER_VALIDATE_INT ) ?: 0;
+ }
}
--- a/salesmanago/src/Admin/Model/ExportModel.php
+++ b/salesmanago/src/Admin/Model/ExportModel.php
@@ -52,7 +52,7 @@
protected $started;
protected $lastSuccess;
protected $packageCount = 0;
- protected $lastExportedPackage = -1; // No packages have been exported. 0 will be the first one.
+ protected $lastExportedPackage = -1;
protected $status = 'unknown';
protected $message = '';
protected $productIdentifierType = self::DEFAULT_PRODUCT_IDENTIFIER_TYPE;
@@ -66,7 +66,6 @@
$this->ProductBuilder = new ProductBuilder( $AdminModel );
}
-
/**
* @param int $packageCount
*/
@@ -113,7 +112,7 @@
* @param string $message
*/
public function setMessage( $message ) {
- $this->message = $message;
+ $this->message = $this->sanitize_output( $message );
}
/**
@@ -137,15 +136,32 @@
*/
public function parseArgs() {
try {
- $data = json_decode( base64_decode( $_REQUEST['data'] ) );
+ if ( ! isset( $_REQUEST['data'] ) ) {
+ throw new Exception( 'Missing request data' );
+ }
+
+ $raw_data = sanitize_text_field( $_REQUEST['data'] );
+ $decoded = base64_decode( $raw_data, true );
+
+ if ( false === $decoded ) {
+ throw new Exception( 'Invalid base64 encoding' );
+ }
+
+ $data = json_decode( $decoded );
+
+ if ( json_last_error() !== JSON_ERROR_NONE || ! is_object( $data ) ) {
+ throw new Exception( 'Invalid JSON data' );
+ }
- $this->dateFrom = empty( $data->dateFrom )
+ $raw_date_from = isset( $data->dateFrom ) ? $data->dateFrom : '';
+ $this->dateFrom = empty( $raw_date_from )
? '2000-01-01'
- : $data->dateFrom;
+ : $this->validate_date_format( sanitize_text_field( $raw_date_from ) );
- $this->dateTo = empty( $data->dateTo )
+ $raw_date_to = isset( $data->dateTo ) ? $data->dateTo : '';
+ $this->dateTo = empty( $raw_date_to )
? date( 'Y-m-d', time() + 86400 )
- : date( 'Y-m-d', strtotime( $data->dateTo ) + 86400 );
+ : date( 'Y-m-d', strtotime( $this->validate_date_format( sanitize_text_field( $raw_date_to ) ) ) + 86400 );
$this->tags = empty( $data->tags )
? array()
@@ -163,24 +179,27 @@
? time()
: (int) $data->started;
- $this->productIdentifierType = empty( $data->identifierType )
+ $raw_identifier = isset( $data->identifierType ) ? $data->identifierType : '';
+ $this->productIdentifierType = empty( $raw_identifier )
? self::DEFAULT_PRODUCT_IDENTIFIER_TYPE
- : $data->identifierType;
+ : $this->validate_identifier_type( sanitize_text_field( $raw_identifier ) );
$this->lastSuccess = empty( $data->lastSuccess )
? 0
: (int) $data->lastSuccess;
- $this->statuses = self::checkStatusesFromRequest( $data->statuses )
- ? 'wc-completed'
- : $data->statuses;
+ $raw_statuses = isset( $data->statuses ) ? sanitize_text_field( $data->statuses ) : '';
+ $this->statuses = self::checkStatusesFromRequest( $raw_statuses )
+ ? $raw_statuses
+ : 'wc-completed';
- $this->exportAs = empty( $data->exportAs ) || ! in_array( $data->exportAs, self::ALLOWED_TYPES )
+ $raw_export_as = isset( $data->exportAs ) ? $data->exportAs : '';
+ $this->exportAs = empty( $raw_export_as ) || ! in_array( $raw_export_as, self::ALLOWED_TYPES, true )
? self::PURCHASE
- : $data->exportAs;
+ : sanitize_text_field( $raw_export_as );
} catch ( Exception $e ) {
- $this->message = $e->getMessage();
+ $this->message = $this->sanitize_output( $e->getMessage() );
$this->status = self::FAILED;
$this->buildResponse();
}
@@ -199,7 +218,7 @@
'type' => $this->exportType,
'tags' => $this->tags,
'status' => $this->status,
- 'message' => $this->message,
+ 'message' => $this->sanitize_output( $this->message ),
'identifierType' => $this->productIdentifierType,
'dateFrom' => $this->dateFrom,
'dateTo' => date( 'Y-m-d', strtotime( $this->dateTo ) - 86400 ),
@@ -207,12 +226,9 @@
'statuses' => $this->statuses,
'exportAs' => $this->exportAs,
);
- echo( wp_json_encode( $response ) );
- die();
+ wp_send_json( $response );
}
-
-
/**
* @param $collection
* @return ContactsCollection|null
@@ -236,42 +252,42 @@
/* Contact */
$customer['name'] = trim(
- ( isset( $customer['first_name'] ) ? $customer['first_name'] : '' ) .
+ ( isset( $customer['first_name'] ) ? sanitize_text_field( $customer['first_name'] ) : '' ) .
' ' .
- ( isset( $customer['last_name'] ) ? $customer['last_name'] : '' )
+ ( isset( $customer['last_name'] ) ? sanitize_text_field( $customer['last_name'] ) : '' )
);
$Contact
- ->setEmail( isset( $customer['email'] ) ? $customer['email'] : null )
- ->setName( isset( $customer['name'] ) ? $customer['name'] : null )
- ->setExternalId( isset( $customer['user_id'] ) ? $customer['user_id'] : null )
- ->setPhone( isset( $customer['phone'] ) ? $customer['phone'] : null );
+ ->setEmail( isset( $customer['email'] ) ? sanitize_email( $customer['email'] ) : null )
+ ->setName( isset( $customer['name'] ) ? sanitize_text_field( $customer['name'] ) : null )
+ ->setExternalId( isset( $customer['user_id'] ) ? (int) $customer['user_id'] : null )
+ ->setPhone( isset( $customer['phone'] ) ? sanitize_text_field( $customer['phone'] ) : null );
/* Address */
$customer['address'] = trim(
- ( isset( $customer['address_1'] ) ? $customer['address_1'] : '' ) .
+ ( isset( $customer['address_1'] ) ? sanitize_text_field( $customer['address_1'] ) : '' ) .
' ' .
- ( isset( $customer['address_2'] ) ? $customer['address_2'] : '' )
+ ( isset( $customer['address_2'] ) ? sanitize_text_field( $customer['address_2'] ) : '' )
);
$Address
- ->setStreetAddress( isset( $customer['address'] ) ? $customer['address'] : null )
- ->setCity( isset( $customer['city'] ) ? $customer['city'] : null )
- ->setZipCode( isset( $customer['postcode'] ) ? $customer['postcode'] : null );
+ ->setStreetAddress( isset( $customer['address'] ) ? sanitize_text_field( $customer['address'] ) : null )
+ ->setCity( isset( $customer['city'] ) ? sanitize_text_field( $customer['city'] ) : null )
+ ->setZipCode( isset( $customer['postcode'] ) ? sanitize_text_field( $customer['postcode'] ) : null );
/* Options */
$Options
->setTags( empty( $this->tags ) ? array() : $this->tags )
- ->setCreatedOn( isset( $customer['created_on'] ) ? $customer['created_on'] : null );
+ ->setCreatedOn( isset( $customer['created_on'] ) ? sanitize_text_field( $customer['created_on'] ) : null );
$ContactsCollection->addItem( $Contact );
}
return $ContactsCollection;
} catch ( Exception $e ) {
- $this->message = $e->getViewMessage();
+ $this->message = $this->sanitize_output( method_exists( $e, 'getViewMessage' ) ? $e->getViewMessage() : $e->getMessage() );
$this->status = self::FAILED;
$this->buildResponse();
} catch ( Exception $e ) {
- $this->message = $e->getMessage();
+ $this->message = $this->sanitize_output( $e->getMessage() );
$this->status = self::FAILED;
$this->buildResponse();
}
@@ -301,20 +317,20 @@
}
$Event
- ->setEmail( isset( $event['email'] ) ? $event['email'] : null )
+ ->setEmail( isset( $event['email'] ) ? sanitize_email( $event['email'] ) : null )
->setDate( $date )
- ->setDescription( isset( $event['description'] ) ? $event['description'] : null )
- ->setProducts( isset( $event['products'] ) ? $event['products'] : null )
- ->setValue( isset( $event['value'] ) ? $event['value'] : null )
- ->setContactExtEventType( isset( $event['contactExtEventType'] ) ? $event['contactExtEventType'] : self::PURCHASE )
- ->setExternalId( isset( $event['externalId'] ) ? $event['externalId'] : null )
- ->setShopDomain( isset( $event['shopDomain'] ) ? $event['shopDomain'] : get_site_url() )
- ->setLocation( ! empty( $this->Configuration->getLocation() ) ? $this->Configuration->getLocation() : md5( get_site_url() ) )
+ ->setDescription( isset( $event['description'] ) ? sanitize_text_field( $event['description'] ) : null )
+ ->setProducts( isset( $event['products'] ) ? sanitize_text_field( $event['products'] ) : null )
+ ->setValue( isset( $event['value'] ) ? floatval( $event['value'] ) : null )
+ ->setContactExtEventType( isset( $event['contactExtEventType'] ) ? sanitize_text_field( $event['contactExtEventType'] ) : self::PURCHASE )
+ ->setExternalId( isset( $event['externalId'] ) ? sanitize_text_field( $event['externalId'] ) : null )
+ ->setShopDomain( isset( $event['shopDomain'] ) ? esc_url_raw( $event['shopDomain'] ) : get_site_url() )
+ ->setLocation( ! empty( $this->Configuration->getLocation() ) ? sanitize_text_field( $this->Configuration->getLocation() ) : md5( get_site_url() ) )
->setDetails(
array(
- '1' => isset( $event['detail1'] ) ? $event['detail1'] : null,
- '2' => isset( $event['detail2'] ) ? $event['detail2'] : null,
- '3' => isset( $event['detail3'] ) ? $event['detail3'] : null,
+ '1' => isset( $event['detail1'] ) ? sanitize_text_field( $event['detail1'] ) : null,
+ '2' => isset( $event['detail2'] ) ? sanitize_text_field( $event['detail2'] ) : null,
+ '3' => isset( $event['detail3'] ) ? sanitize_text_field( $event['detail3'] ) : null,
)
);
@@ -322,12 +338,12 @@
}
return $EventsCollection;
} catch ( Exception $e ) {
- $this->message = $e->getViewMessage();
+ $this->message = $this->sanitize_output( method_exists( $e, 'getViewMessage' ) ? $e->getViewMessage() : $e->getMessage() );
$this->status = self::FAILED;
$this->buildResponse();
} catch ( Exception $e ) {
- $this->message = $e->getMessage();
+ $this->message = $this->sanitize_output( $e->getMessage() );
$this->status = self::FAILED;
$this->buildResponse();
}
@@ -348,6 +364,7 @@
$query .= 'SELECT COUNT(*) AS count FROM (';
}
+ // Build base query with placeholders
$query .= "
SELECT DISTINCT
B.meta_value as first_name,
@@ -399,22 +416,30 @@
WHERE
A.post_type = 'shop_order'
+ ";
+
+ $query .= $this->db->prepare( "
AND
- A.post_date >= '{$this->dateFrom}'
+ A.post_date >= %s
AND
- A.post_date <= '{$this->dateTo}'
- ";
+ A.post_date <= %s
+ ", $this->dateFrom, $this->dateTo );
if ( ! empty( $this->Configuration->getIgnoredDomains() ) ) {
- $query .= "AND SUBSTRING_INDEX(K.meta_value, '@', -1) NOT IN('" . implode( "','", $this->Configuration->getIgnoredDomains() ) . "')";
+ $ignored_domains = array_map( 'sanitize_text_field', $this->Configuration->getIgnoredDomains() );
+ if ( ! empty( $ignored_domains ) ) {
+ $placeholders = implode( ',', array_fill( 0, count( $ignored_domains ), '%s' ) );
+ $query .= $this->db->prepare( "
+ AND SUBSTRING_INDEX(K.meta_value, '@', -1) NOT IN($placeholders)
+ ", ...$ignored_domains );
+ }
}
if ( ! $count ) {
- $query .= "
- LIMIT {$limit}
-
- OFFSET {$offset}
- ";
+ $query .= $this->db->prepare( "
+ LIMIT %d
+ OFFSET %d
+ ", $limit, $offset );
}
if ( $count ) {
@@ -423,7 +448,7 @@
return trim( preg_replace( '/ss+/', ' ', $query ) );
} catch ( Exception $e ) {
- $this->message = $e->getMessage();
+ $this->message = $this->sanitize_output( $e->getMessage() );
$this->status = self::FAILED;
$this->buildResponse();
}
@@ -488,16 +513,16 @@
? $WcProduct->get_parent_id()
: $WcProduct->get_id();
$prodArr['names'][] = ( $WcProduct->get_name() )
- ? $WcProduct->get_name()
+ ? sanitize_text_field( $WcProduct->get_name() )
: '';
$prodArr['quantity'][] = ( $product->get_quantity() )
- ? $product->get_quantity()
+ ? (int) $product->get_quantity()
: '';
$prodArr['variationIds'][] = ( $WcProduct->get_id() )
? $WcProduct->get_id()
: '';
$prodArr['skus'][] = ( $WcProduct->get_sku() )
- ? $WcProduct->get_sku()
+ ? sanitize_text_field( $WcProduct->get_sku() )
: '';
}
}
@@ -511,12 +536,12 @@
return $data;
}
} catch ( Exception $e ) {
- $this->message = $e->getViewMessage();
+ $this->message = $this->sanitize_output( method_exists( $e, 'getViewMessage' ) ? $e->getViewMessage() : $e->getMessage() );
$this->status = self::FAILED;
$this->buildResponse();
} catch ( Exception $e ) {
- $this->message = $e->getMessage();
+ $this->message = $this->sanitize_output( $e->getMessage() );
$this->status = self::FAILED;
$this->buildResponse();
}
@@ -530,44 +555,44 @@
$exportAs = self::PURCHASE
) {
$data = array(
- 'email' => $order->get_billing_email(),
+ 'email' => sanitize_email( $order->get_billing_email() ),
'date' => ( $order->get_date_created()->getTimestamp() )
? $order->get_date_created()->getTimestamp() * 1000
: '',
'description' => ( $order->get_payment_method_title() )
- ? $order->get_payment_method_title()
+ ? sanitize_text_field( $order->get_payment_method_title() )
: '',
'products' => is_array( $prodArr['ids'] )
- ? implode( ',', $prodArr['ids'] )
+ ? implode( ',', array_map( 'intval', $prodArr['ids'] ) )
: $prodArr['ids'],
'value' => ( $order->get_total() )
- ? $order->get_total()
+ ? floatval( $order->get_total() )
: '',
- 'contactExtEventType' => $exportAs,
+ 'contactExtEventType' => sanitize_text_field( $exportAs ),
'detail1' => is_array( $prodArr['names'] )
- ? implode( ',', $prodArr['names'] )
+ ? implode( ',', array_map( 'sanitize_text_field', $prodArr['names'] ) )
: '',
'detail2' => ( $order->get_order_key() )
- ? $order->get_order_key()
+ ? sanitize_text_field( $order->get_order_key() )
: '',
'detail3' => is_array( $prodArr['quantity'] )
- ? implode( '/', $prodArr['quantity'] )
+ ? implode( '/', array_map( 'intval', $prodArr['quantity'] ) )
: $prodArr['quantity'],
'externalId' => ( $order->get_id() )
- ? $order->get_id()
+ ? (int) $order->get_id()
: '',
- 'shopDomain' => get_site_url(),
+ 'shopDomain' => esc_url_raw( get_site_url() ),
);
$skus = is_array( $prodArr['skus'] )
- ? implode( ',', $prodArr['skus'] )
+ ? implode( ',', array_map( 'sanitize_text_field', $prodArr['skus'] ) )
: $prodArr['skus'];
$ids = is_array( $prodArr['ids'] )
- ? implode( ',', $prodArr['ids'] )
+ ? implode( ',', array_map( 'intval', $prodArr['ids'] ) )
: $prodArr['ids'];
$variationIds = is_array( $prodArr['variationIds'] )
- ? implode( ',', $prodArr['variationIds'] )
+ ? implode( ',', array_map( 'intval', $prodArr['variationIds'] ) )
: $prodArr['variationIds'];
switch ( $productIdentifierType ) {
@@ -597,16 +622,16 @@
*/
public function getExportDataForReporting() {
$details = array(
- 'exportType' => $this->exportType,
+ 'exportType' => sanitize_text_field( $this->exportType ),
'dateFrom' => $this->dateFrom,
'dateTo' => $this->dateTo,
'tags' => $this->tags,
- 'lastExportedPackage' => $this->lastExportedPackage,
- 'started' => $this->started,
- 'lastSuccess' => $this->lastSuccess,
- 'packageCount' => $this->packageCount,
- 'status' => $this->status,
- 'message' => $this->message,
+ 'lastExportedPackage' => (int) $this->lastExportedPackage,
+ 'started' => (int) $this->started,
+ 'lastSuccess' => (int) $this->lastSuccess,
+ 'packageCount' => (int) $this->packageCount,
+ 'status' => sanitize_text_field( $this->status ),
+ 'message' => $this->sanitize_output( $this->message ),
);
return wp_json_encode( $details );
}
@@ -621,9 +646,10 @@
return false;
}
$wcOrderStatuses = Helper::wcGetOrderStatuses();
- $orderStatuses = explode( ',', $statuses );
+ $allowedStatuses = array_keys( $wcOrderStatuses );
+ $orderStatuses = explode( ',', sanitize_text_field( $statuses ) );
foreach ( $orderStatuses as $status ) {
- if ( ! in_array( $status, $wcOrderStatuses ) ) {
+ if ( ! in_array( sanitize_text_field( $status ), $allowedStatuses, true ) ) {
return false;
}
}
@@ -639,12 +665,12 @@
* @throws Exception
*/
protected function countProducts() {
- $query = "
+ $query = $this->db->prepare( "
SELECT COUNT(ID) FROM {$this->db->posts}
- WHERE (post_type = 'product' OR post_type = 'product_variation')
+ WHERE (post_type = %s OR post_type = %s)
AND post_name != ''
- AND post_status != 'auto-draft';
- ";
+ AND post_status != %s;
+ ", 'product', 'product_variation', 'auto-draft' );
return $this->db->get_var( trim( preg_replace( '/ss+/', ' ', $query ) ) );
}
@@ -660,7 +686,7 @@
$limit = self::PRODUCT_PACKAGE_SIZE;
$offset = $limit * ( $this->lastExportedPackage + 1 );
- $query = "
+ $query = $this->db->prepare( "
SELECT
A.ID as productId,
A.post_title as name,
@@ -689,17 +715,17 @@
LEFT JOIN
{$this->db->postmeta} as F
ON A.id = F.post_id AND F.meta_key = '_sku'
- WHERE ( post_type = 'product' OR post_type = 'product_variation' )
+ WHERE ( post_type = %s OR post_type = %s )
AND post_name != ''
- AND post_status != 'auto-draft'
+ AND post_status != %s
GROUP BY A.ID
- LIMIT {$limit}
- OFFSET {$offset};";
+ LIMIT %d
+ OFFSET %d;", 'product', 'product_variation', 'auto-draft', $limit, $offset );
return trim( preg_replace( '/ss+/', ' ', $query ) );
} catch ( Exception $e ) {
- error_log( $e->getMessage() );
- throw new Exception( $e->getMessage() );
+ error_log( $this->sanitize_output( $e->getMessage() ) );
+ throw new Exception( $this->sanitize_output( $e->getMessage() ) );
}
}
@@ -710,7 +736,7 @@
* @throws Exception
*/
public function prepareProductsForExport( $products, $productIdentifierType ) {
- return $this->ProductBuilder->add_products_to_collection( $products, $productIdentifierType );
+ return $this->ProductBuilder->add_products_to_collection( $products, $this->validate_identifier_type( sanitize_text_field( $productIdentifierType ) ) );
}
/**
@@ -719,7 +745,22 @@
* @throws Exception
*/
public function parseProductExportArgs() {
- $data = json_decode( base64_decode( $_REQUEST['data'] ) );
+ if ( ! isset( $_REQUEST['data'] ) ) {
+ throw new Exception( 'Missing request data' );
+ }
+
+ $raw_data = sanitize_text_field( $_REQUEST['data'] );
+ $decoded = base64_decode( $raw_data, true );
+
+ if ( false === $decoded ) {
+ throw new Exception( 'Invalid base64 encoding' );
+ }
+
+ $data = json_decode( $decoded );
+
+ if ( json_last_error() !== JSON_ERROR_NONE || ! is_object( $data ) ) {
+ throw new Exception( 'Invalid JSON data' );
+ }
$this->setExportType( self::PRODUCTS );
@@ -744,11 +785,11 @@
}
if ( isset( $data->message ) ) {
- $this->message = $data->message;
+ $this->message = $this->sanitize_output( $data->message );
}
if ( isset( $data->status ) ) {
- $this->status = $data->status;
+ $this->status = sanitize_text_field( $data->status );
switch ( $this->status ) {
case self::FAILED:
throw new Exception( $this->message ?? 'Export failed' );
@@ -772,12 +813,11 @@
'started' => $this->started,
'lastSuccess' => time(),
'type' => $this->exportType,
- 'status' => $this->status,
- 'message' => $this->message,
+ 'status' => sanitize_text_field( $this->status ),
+ 'message' => $this->sanitize_output( $this->message ),
'count' => $this->count,
);
- echo wp_json_encode( $response );
- die(); // Due to WP ajax.
+ wp_send_json( $response );
}
/**
@@ -797,8 +837,7 @@
'message' => 'Expired API Key. Refresh the page and add a new API key',
'count' => $this->count,
);
- echo json_encode( $response );
- die(); // Due to WP ajax
+ wp_send_json( $response );
}
/**
@@ -839,4 +878,52 @@
}
return $products;
}
+
+ // ========================================================================
+ // SECURITY HELPER METHODS (for sanitization/validation)
+ // ========================================================================
+
+ /**
+ * Sanitize output to prevent XSS and log injection
+ *
+ * @param string $text Raw text to sanitize
+ * @return string Sanitized text
+ */
+ private function sanitize_output( $text ) {
+ if ( ! is_string( $text ) ) {
+ return '';
+ }
+ $sanitized = preg_replace( '/[rntx00-x1Fx7F]/', ' ', $text );
+ // Trim and limit length to prevent log flooding/DoS
+ return substr( trim( $sanitized ), 0, 2048 );
+ }
+
+ /**
+ * Validate date format (YYYY-MM-DD)
+ *
+ * @param string $date Raw date string
+ * @return string Validated date or default
+ */
+ private function validate_date_format( $date ) {
+ if ( preg_match( '/^d{4}-d{2}-d{2}$/', $date ) ) {
+ return $date;
+ }
+ // Return safe default for invalid dates
+ return '2000-01-01';
+ }
+
+ /**
+ * Validate product identifier type against allowed values
+ *
+ * @param string $type Raw identifier type
+ * @return string Validated type or default
+ */
+ private function validate_identifier_type( $type ) {
+ $allowed = array(
+ self::DEFAULT_PRODUCT_IDENTIFIER_TYPE,
+ self::PRODUCT_IDENTIFIER_TYPE_SKU,
+ self::PRODUCT_IDENTIFIER_TYPE_VARIANT,
+ );
+ return in_array( $type, $allowed, true ) ? $type : self::DEFAULT_PRODUCT_IDENTIFIER_TYPE;
+ }
}
--- a/salesmanago/src/Includes/SecureHelper.php
+++ b/salesmanago/src/Includes/SecureHelper.php
@@ -10,6 +10,14 @@
class SecureHelper
{
+ private const AJAX_ACTIONS = array(
+ 'salesmanago_export_count_contacts',
+ 'salesmanago_export_contacts',
+ 'salesmanago_export_count_events',
+ 'salesmanago_export_events',
+ 'salesmanago_export_products'
+ );
+
protected static $instance = [
'login',
'logout',
@@ -20,8 +28,6 @@
'addProductCatalog',
'setActiveCatalog',
'acknowledgeProductApiError',
-
-
'salesmanago_refresh_catalogs',
'salesmanago_settings_save'
];
@@ -34,7 +40,6 @@
* @return bool
*/
public static function validate_nonce($nonce, $action) {
-
if ( function_exists( 'current_user_can' ) && ! current_user_can( 'manage_options' ) ) {
return false;
}
@@ -49,22 +54,23 @@
'addProductCatalog',
'setActiveCatalog',
'acknowledgeProductApiError',
-
'salesmanago_refresh_catalogs',
'salesmanago_settings_save',
-
'salesmanago_generate_swjs',
-
);
- if ( in_array( $_REQUEST['action'], $actions_requiring_nonce, true )
+ $request_action = isset( $_REQUEST['action'] ) ? sanitize_text_field( $_REQUEST['action'] ) : '';
+
+ $action_to_verify = ! empty( $action ) ? $action : $request_action;
+
+ if ( in_array( $request_action, $actions_requiring_nonce, true )
&& function_exists( 'wp_verify_nonce' )
) {
- $action = $_REQUEST['action'];
-
- $nonce = $_REQUEST['sm_nonce'] ?? ($_REQUEST['nonce'] ?? '');
+ $nonce_from_request = isset( $_REQUEST['sm_nonce'] )
+ ? sanitize_text_field( $_REQUEST['sm_nonce'] )
+ : ( isset( $_REQUEST['nonce'] ) ? sanitize_text_field( $_REQUEST['nonce'] ) : '' );
- if ( ! $nonce || ! wp_verify_nonce( $nonce, $action ) ) {
+ if ( ! $nonce_from_request || ! wp_verify_nonce( $nonce_from_request, $action_to_verify ) ) {
MessageEntity::getInstance()->addMessage( 'Not authorized. Please refresh the view', 'error', 403);
return false;
}
@@ -77,29 +83,18 @@
* Validates nonce for ajax requests
*
* @param string $action
+ * @return void Exit when validation fails
*/
public static function validate_ajax_nonce($action) {
- if ( function_exists( 'current_user_can' ) && ! current_user_can( 'manage_options' ) ) {
- return false;
- }
+ $request_action = sanitize_text_field( $_REQUEST['action'] ?? '' );
- $actions_requiring_nonce = [
- 'salesmanago_export_count_contacts',
- 'salesmanago_export_contacts',
- 'salesmanago_export_count_events',
- 'salesmanago_export_events',
- 'salesmanago_export_products'
- ];
-
- if (! in_array($action, $actions_requiring_nonce, true)) {
- return false;
- }
-
- if ( function_exists( 'check_ajax_referer' ) ) {
- check_ajax_referer( 'salesmanago_admin', 'sm_nonce' );
- }
- if ( ! current_user_can( 'manage_options' ) ) {
+ if (
+ $request_action !== $action
+ || ! in_array($request_action, self::AJAX_ACTIONS, true)
+ || ! check_ajax_referer( 'salesmanago_admin', 'sm_nonce', false )
+ || ! current_user_can( 'manage_options' )
+ ) {
wp_send_json_error( array( 'message' => 'forbidden' ), 403 );
}
}
-}
No newline at end of file
+}
--- a/salesmanago/vendor/autoload.php
+++ b/salesmanago/vendor/autoload.php
@@ -9,4 +9,4 @@
require_once __DIR__ . '/composer/autoload_real.php';
-return ComposerAutoloaderInitdf0785160b05926b54427aa10234a6db::getLoader();
+return ComposerAutoloaderInit3f48638f92ecc3ba847c57999eff8851::getLoader();
--- a/salesmanago/vendor/composer/autoload_classmap.php
+++ b/salesmanago/vendor/composer/autoload_classmap.php
@@ -205,6 +205,4 @@
'bhr\Includes\Helper' => $baseDir . '/src/Includes/Helper.php',
'bhr\Includes\SecureHelper' => $baseDir . '/src/Includes/SecureHelper.php',
'bhr\Includes\SmProduct' => $baseDir . '/src/Includes/SmProduct.php',
- 'tests\Unit\Model\AdminModelTest' => $baseDir . '/tests/Unit/Model/AdminModelTest.php',
- 'tests\Unit\TestCase' => $baseDir . '/tests/Unit/TestCase.php',
);
--- a/salesmanago/vendor/composer/autoload_real.php
+++ b/salesmanago/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
-class ComposerAutoloaderInitdf0785160b05926b54427aa10234a6db
+class ComposerAutoloaderInit3f48638f92ecc3ba847c57999eff8851
{
private static $loader;
@@ -24,12 +24,12 @@
require __DIR__ . '/platform_check.php';
- spl_autoload_register(array('ComposerAutoloaderInitdf0785160b05926b54427aa10234a6db', 'loadClassLoader'), true, true);
+ spl_autoload_register(array('ComposerAutoloaderInit3f48638f92ecc3ba847c57999eff8851', 'loadClassLoader'), true, true);
self::$loader = $loader = new ComposerAutoloadClassLoader(dirname(__DIR__));
- spl_autoload_unregister(array('ComposerAutoloaderInitdf0785160b05926b54427aa10234a6db', 'loadClassLoader'));
+ spl_autoload_unregister(array('ComposerAutoloaderInit3f48638f92ecc3ba847c57999eff8851', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
- call_user_func(ComposerAutoloadComposerStaticInitdf0785160b05926b54427aa10234a6db::getInitializer($loader));
+ call_user_func(ComposerAutoloadComposerStaticInit3f48638f92ecc3ba847c57999eff8851::getInitializer($loader));
$loader->register(true);
--- a/salesmanago/vendor/composer/autoload_static.php
+++ b/salesmanago/vendor/composer/autoload_static.php
@@ -4,7 +4,7 @@
namespace ComposerAutoload;
-class ComposerStaticInitdf0785160b05926b54427aa10234a6db
+class ComposerStaticInit3f48638f92ecc3ba847c57999eff8851
{
public static $prefixLengthsPsr4 = array (
't' =>
@@ -236,16 +236,14 @@
'bhr\Includes\Helper' => __DIR__ . '/../..' . '/src/Includes/Helper.php',
'bhr\Includes\SecureHelper' => __DIR__ . '/../..' . '/src/Includes/SecureHelper.php',
'bhr\Includes\SmProduct' => __DIR__ . '/../..' . '/src/Includes/SmProduct.php',
- 'tests\Unit\Model\AdminModelTest' => __DIR__ . '/../..' . '/tests/Unit/Model/AdminModelTest.php',
- 'tests\Unit\TestCase' => __DIR__ . '/../..' . '/tests/Unit/TestCase.php',
);
public static function getInitializer(ClassLoader $loader)
{
return Closure::bind(function () use ($loader) {
- $loader->prefixLengthsPsr4 = ComposerStaticInitdf0785160b05926b54427aa10234a6db::$prefixLengthsPsr4;
- $loader->prefixDirsPsr4 = ComposerStaticInitdf0785160b05926b54427aa10234a6db::$prefixDirsPsr4;
- $loader->classMap = ComposerStaticInitdf0785160b05926b54427aa10234a6db::$classMap;
+ $loader->prefixLengthsPsr4 = ComposerStaticInit3f48638f92ecc3ba847c57999eff8851::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInit3f48638f92ecc3ba847c57999eff8851::$prefixDirsPsr4;
+ $loader->classMap = ComposerStaticInit3f48638f92ecc3ba847c57999eff8851::$classMap;
}, null, ClassLoader::class);
}
--- a/salesmanago/vendor/composer/installed.php
+++ b/salesmanago/vendor/composer/installed.php
@@ -1,8 +1,8 @@
<?php return array(
'root' => array(
'name' => 'salesmanago/wordpress',
- 'pretty_version' => '3.11.2',
- 'version' => '3.11.2.0',
+ 'pretty_version' => '3.11.3',
+ 'version' => '3.11.3.0',
'reference' => NULL,
'type' => 'library',
'install_path' => __DIR__ . '/../../',
@@ -20,8 +20,8 @@
'dev_requirement' => false,
),
'salesmanago/wordpress' => array(
- 'pretty_version' => '3.11.2',
- 'version' => '3.11.2.0',
+ 'pretty_version' => '3.11.3',
+ 'version' => '3.11.3.0',
'reference' => NULL,
'type' => 'library',
'install_path' => __DIR__ . '/../../',