CVE-2023-5861 (PHP, published 2023-10-31T01:15Z)
Description: value: Cross-site Scripting (XSS) - Stored in GitHub repository microweber/microweber prior to 2.0.
Severity: nan (CVSS v3 base score: 4.8)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/microweber/microweber
Files changed:
src/MicroweberPackages/Cart/CartManager.php
src/MicroweberPackages/Customer/tests/CustomerCheckoutTest.php
src/MicroweberPackages/Order/OrderManager.php
src/MicroweberPackages/Shop/tests/CheckoutClientTest.php
src/MicroweberPackages/Shop/tests/CheckoutTest.php
Commit message: update


Vulnerable code:
                if (is_array($cont) and isset($cont['title'])) {
use MicroweberPackages\Core\tests\TestCase;
use MicroweberPackages\Utils\Mail\MailSender;

        $this->assertEquals($prices_data['Price'],$productPrice);
 
         \Config::set('mail.transport', 'array');

    public function place_order($place_order)

        $productQuery = \MicroweberPackages\Product\Models\Product::query();
        $productQuery = $productQuery->whereHas('orders');
        $products = $productQuery->get();
        $this->assertTrue($products->isEmpty());
        $productQuery = \MicroweberPackages\Product\Models\Product::query();
        $productQuery = $productQuery->whereHas('orders');
        $products = $productQuery->get();
        $this->assertTrue($products->isEmpty());

Fixed code:
                if (is_array($cont) and isset($cont['title']) and $cont['title']) {
            if(!isset($data['title']) or $data['title'] == false){
                $data['title'] = 'Product '.$cart['rel_id'];
            }


use MicroweberPackages\Core\tests\TestCase;
        $this->assertEquals($prices_data['Price'], $productPrice);

        \Config::set('mail.transport', 'array');
    public function testCheckoutCustomerWithXss()
    {

        $this->_addProductToCart('Product 1');
        $this->_addProductToCart('Product 2');
        $this->_addProductToCart('Product 3');
        $this->_addProductToCart('Product 4');
        $xss = '<style>@keyframes x{}</style><xss style="animation-name:x" onanimationend="alert(document.cookie)"></xss>';
        $checkoutDetails = array();
        $checkoutDetails['email'] = 'client_' . uniqid() . '@microweber.com';
        $checkoutDetails['first_name'] = 'Client First Name<script>alert(1)</script>' . $xss;
        $checkoutDetails['last_name'] = 'Microweber Last Name' . $xss;
        $checkoutDetails['phone'] = '08812345' . rand(100, 999) . $xss;
        $checkoutDetails['address'] = 'Business Park, Mladost 4' . $xss;
        $checkoutDetails['address2'] = 'Business Park, Mladost 6' . $xss;
        $checkoutDetails['city'] = 'Sofia' . $xss;
        $checkoutDetails['state'] = 'Sofia City' . $xss;
        $checkoutDetails['country'] = 'Bulgaria' . $xss;
        $checkoutDetails['zip'] = '1000' . $xss;


        $checkout = new CheckoutManager();
        $checkoutStatus = $checkout->checkout($checkoutDetails);

        $this->assertArrayHasKey('success', $checkoutStatus);
        $this->assertArrayHasKey('id', $checkoutStatus);


        // Find customer
        $customer = Customer::where('email', $checkoutDetails['email'])->first();

        $this->assertEquals($customer->email, $checkoutDetails['email']);
        $this->assertNotEquals($customer->first_name, $checkoutDetails['first_name']);
        $this->assertNotEquals($customer->last_name, $checkoutDetails['last_name']);
        $this->assertNotEquals($customer->phone, $checkoutDetails['phone']);

        // Find customer
        $address = Address::where('customer_id', $customer->id)->first();

        $this->assertNotEquals($address->phone, $checkoutDetails['phone']);
        $this->assertNotEquals($address->address_street_1, $checkoutDetails['address']);
        $this->assertNotEquals($address->address_street_2, $checkoutDetails['address2']);
        $this->assertNotEquals($address->city, $checkoutDetails['city']);
        $this->assertNotEquals($address->zip, $checkoutDetails['zip']);
        $this->assertNotEquals($address->state, $checkoutDetails['state']);


    }
    public function place_order($place_order = array())
        if (empty($place_order)) {
            return;
        }
        array_walk_recursive(
            $place_order,
            function(&$string) {
                if (is_string($string)) {
                    $string = trim(strip_tags($string));
                }
            }
        );
        $place_order = xss_clean($place_order);
<?php
namespace MicroweberPackages\Shop\tests;

use MicroweberPackages\Checkout\CheckoutManager;
use MicroweberPackages\Core\tests\TestCase;


class CheckoutClientTest extends TestCase
{
    public static $content_id = 1;

    private function _addProductToCart($title)
    {
        app()->database_manager->extended_save_set_permission(true);

        $productPrice = rand(1, 4444);

        $params = array(
            'title' => $title,
            'content_type' => 'product',
            'subtype' => 'product',
            'custom_fields_advanced' => array(
                array('type' => 'dropdown', 'name' => 'Color', 'value' => array('Purple', 'Blue')),
                array('type' => 'price', 'name' => 'Price', 'value' => $productPrice),

            ),
            'is_active' => 1,);


        $saved_id = save_content($params);
        $get = get_content_by_id($saved_id);

        $this->assertEquals($saved_id, ($get['id']));
        self::$content_id = $saved_id;

        $add_to_cart = array(
            'content_id' => self::$content_id,
            'price' => $productPrice,
        );
        $cart_add = update_cart($add_to_cart);

        $this->assertEquals(isset($cart_add['success']), true);
        $this->assertEquals(isset($cart_add['product']), true);
        $this->assertEquals($cart_add['product']['price'], $productPrice);
    }

    public function testCheckoutClientNames()
    {
        empty_cart();


        $this->_addProductToCart('CheckoutClientTestProduct 1');
        $this->_addProductToCart('CheckoutClientTestProduct 2');
        $this->_addProductToCart('CheckoutClientTestProduct 3');
        $this->_addProductToCart('CheckoutClientTestProduct 4');

        $email = 'client+'.uniqid('testCheckoutClientNames').'test@microweber.com';
        $checkoutDetails = array();
        $checkoutDetails['email'] = $email;
        $checkoutDetails['first_name'] = 'Client';
        $checkoutDetails['last_name'] = 'Microweber';
        $checkoutDetails['phone'] = '08812345678';
        $checkoutDetails['address'] = 'Business Park, Mladost 4';
        $checkoutDetails['city'] = 'Sofia';
        $checkoutDetails['state'] = 'Sofia City';
        $checkoutDetails['country'] = 'Bulgaria';
        $checkoutDetails['zip'] = '1000';

        $checkout = new CheckoutManager();
        $checkoutStatus = $checkout->checkout($checkoutDetails);

        $this->assertArrayHasKey('success', $checkoutStatus);
        $this->assertArrayHasKey('id', $checkoutStatus);
        $this->assertArrayHasKey('order_completed', $checkoutStatus);
        $this->assertArrayHasKey('amount', $checkoutStatus);
        $this->assertArrayHasKey('currency', $checkoutStatus);
        $this->assertArrayHasKey('order_status', $checkoutStatus);

        $this->assertEquals($checkoutStatus['order_completed'], 1);
        $this->assertEquals($checkoutStatus['first_name'],  $checkoutDetails['first_name']);
        $this->assertEquals($checkoutStatus['last_name'],  $checkoutDetails['last_name']);
        $this->assertEquals($checkoutStatus['email'],  $checkoutDetails['email']);
        $this->assertEquals($checkoutStatus['country'],  $checkoutDetails['country']);
        $this->assertEquals($checkoutStatus['city'],  $checkoutDetails['city']);
        $this->assertEquals($checkoutStatus['state'],  $checkoutDetails['state']);
        $this->assertEquals($checkoutStatus['zip'],  $checkoutDetails['zip']);
        $this->assertEquals($checkoutStatus['address'],  $checkoutDetails['address']);




    }





}

        $order = get_order_by_id($checkoutStatus);
        $this->assertNotNull($order);
        $this->assertNull($order['amount']);