Ndk design NdkAdvancedCustomizationFields 3.5.0 is vulnerable to Reflected Cross Site Scripting (XSS-T1 of category 1) via createPdf.php and showPreview.php.

Summary

  • CVE ID: CVE-2022-40840 CVE-2022-40841
  • Published at: 2022-11-01
  • Advisory source: github
  • Vendor: PrestaShop
  • Product: NdkAdvancedCustomizationFields
  • Impacted release: <= 3.5.0
  • Product author: ndkdesign
  • Weakness: CWE-79
  • Severity: medium (6.8)

Description

Since we do not have access to the module, we cannot confirm the XSS type, but based on the POC and until proven otherwise, Ndk design NdkAdvancedCustomizationFields 3.5.0 is vulnerable to Reflected Cross Site Scripting (XSS-T1 of category 1) via createPdf.php.

Be warned that, based on the provided POC, the second exploit against showPreview.php could be a [XSS T2 - potentially F2B)(https://security.friendsofpresta.org/modules/2023/02/07/stored-xss.html) - If confirmed, this exploit could pose a critical vulnerability CVSS 3.1 : 9.6/10 (CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N).

CVSS base metrics

  • Attack vector: network
  • Attack complexity: high
  • Privilege required: none
  • User interaction: required
  • Scope: unchanged
  • Confidentiality: high
  • Integrity: high
  • Availability: none

Vector string: CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N

Possible malicious usage

  • Bypass Protection Mechanism
  • Read Application Data
  • Execute Unauthorized Code or Commands

Proof of concept

Exploit CVE-2022-40840:

http://localhost/modules/ndk_advanced_custom_fields/createPdf.php?htmlNodes[0]=<script&htmlNodes[1]=>alert("xss_poc")</&htmlNodes[2]=script>&idCustomer=..&idProduct=..&idCustomization=..
http://localhost/img/render.html

Exploit CVE-2022-40841:

http://localhost/modules/ndk_advanced_custom_fields/showPreview.php?htmlNodes=<script>alert('xss')</script>

Patch

Added a tag-removing line after the setting of $content :

- a/moldules/ndk_advanced_custom_fields/createPdf.php
+ a/moldules/ndk_advanced_custom_fields/createPdf.php
$content.= '</body></html>';
$regex = "~data:image/[a-zA-Z]*;base64,[a-zA-Z0-9+/\\=]*=~"; 
/*$content = preg_replace_callback(
        $regex,
        function ($matches) {
            return base64_decode($matches[0]);
        },
        $content
    );
 */
+ $content = NdkCf::remove_script_tags($content);

file_put_contents(_PS_IMG_DIR_.'scenes/'.'ndkcf/pdf/'.(int) Tools::getValue('idCustomer').'/'.(int) Tools::getValue('idProduct').'/'.(int) Tools::getValue('idCustomization').'/render.html', $content);
- a/moldules/ndk_advanced_custom_fields/showPreview.php
+ a/moldules/ndk_advanced_custom_fields/showPreview.php
include(dirname(__FILE__).'/../../config/config.inc.php');
include(dirname(__FILE__).'/../../init.php');
+ require_once _PS_MODULE_DIR_.'ndk_advanced_custom_fields/models/ndkCf.php';

$content.= '<body style="position:relative;">';
$content .= Tools::getValue('htmlNodes');
$content.= '</body></html>';
+ $content = NdkCf::remove_script_tags($content);

print( $content );

Here is the function’s content :

+    public static function  remove_script_tags($html, $load = false){
+        $dom = new DOMDocument();
+        $dom->loadHTML($html);
+        $script = $dom->getElementsByTagName('script');
+    
+        $remove = [];
+        foreach($script as $item){
+            $remove[] = $item;
+        }
+        //dump($remove);
+    
+        foreach ($remove as $item){
+            $item->parentNode->removeChild($item);
+        }
+    
+        $html = $dom->saveHTML();
+        if($load){
+            $html = preg_replace('/<!DOCTYPE.*?<html>.*?<body><p>/ims', '', $html);
+            $html = str_replace('</p></body></html>', '', $html);
+        }
+        
+        return $html;
+    }

Other recommendations

  • Upgrade the module to the most recent version
  • Upgrade PrestaShop to the latest version to disable multiquery executions (separated by “;”)
  • Systematically escape characters ‘ “ < and > by replacing them with HTML entities and applying strip_tags
  • Limit to the strict minimum the length’s value in database - a database field which allow 10 characters (varchar(10)) is far less dangerous than a field which allow 40+ characters (use cases which can exploit fragmented XSS payloads are very rare)
  • Configure CSP headers (content security policies) by listing externals domains allowed to load assets (such as js files) or being called in XHR transactions (Ajax).
  • If applicable: check against all your frontoffice’s uploaders, uploading files which will be served by your server with mime type application/javascript (like every .js natively) must be strictly forbidden as it must be considered as dangerous as PHP files.
  • Activate OWASP 941’s rules on your WAF (Web application firewall) - be warn that you will probably break your backoffice and you will need to preconfigure some bypasses against these set of rules.

Timeline

Date Action
01-11-2022 GitHub Poc