In the module “NKM GLS” (nkmgls) up to version 3.0.1 from Nukium for PrestaShop, a guest (authenticated customer) can perform XSS injection of type 2 (stored XSS) from FRONT to BACK (F2B) of Category 2 within the funnel order in affected versions.

Note : To succeed in this exploit, the red team needs to pay to convert a cart into a valid order with GLS carrier and require the administrator of the PS to check a specific screen within its backoffice.


  • CVE ID: CVE-2023-47309
  • Published at: 2023-11-14
  • Platform: PrestaShop
  • Product: nkmgls
  • Impacted release: <= 3.0.1 (3.0.2 fixed the vulnerability)
  • Product author: Nukium
  • Weakness: CWE-79
  • Severity: critical (9.0)


As all XSS type 2 (Stored XSS) F2B (Front to Back), there are two steps and a prerequisite.

Prerequisite :

  • The field phone_mobile within table gls_cart_carrier suffers from a type varchar(255) which is large enough to allow dangerous XSS payloads.

Steps :

  • The method NkmGlsCheckoutModuleFrontController::displayAjaxSavePhoneMobile does not properly clean the parameter gls_customer_mobile. pSQL is useless against XSS which exploits HTML tag attributes (Category 2 according to OWASP - pSQL only neutralized Category 1 thanks to its strip_tags).
  • The output in the backoffice is not escaped in the related smarty template that uses it.

CVSS base metrics

  • Attack vector: network
  • Attack complexity: low
  • Privilege required: low
  • User interaction: required
  • Scope: changed
  • Confidentiality: high
  • Integrity: high
  • Availability: high

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

Possible malicious usage

  • Unlock design critical vulnerabilities, see this.

Patch from 3.0.2

--- a/controllers/front/checkout.php
+++ b/controllers/front/checkout.php
@@ -47,2 +47,7 @@ class NkmGlsCheckoutModuleFrontController extends ModuleFrontController
         $phone_mobile = Tools::getValue('gls_customer_mobile');
+        if (!Validate::isPhoneNumber($phone_mobile)) {
+            $return['message'] = 'Please fill-in a valid mobile number (e.g. +XXXXXXXXXXX or 0XXXXXXXXX).';
+            header('Content-Type: application/json');
+            $this->ajaxDie(json_encode($return));
+        }
         $id_carrier = Tools::getValue('id_carrier');
--- a/views/templates/admin/gls_label/label_list.tpl
+++ b/views/templates/admin/gls_label/label_list.tpl
@@ -209,3 +209,3 @@
-                                                        <input class="form-control" type="tel" name="mobile" value="{if !empty($tr.customer_phone_mobile)}{$tr.customer_phone_mobile}{else}{$tr.customer_phone}{/if}" required="required" />
+                                                        <input class="form-control" type="tel" name="mobile" value="{if !empty($tr.customer_phone_mobile)}{$tr.customer_phone_mobile|escape:'html':'UTF-8'}{else}{$tr.customer_phone|escape:'html':'UTF-8'}{/if}" required="required" />

Other recommendations

  • It’s recommended to upgrade to the latest version of the module nkmgls.
  • Systematically escape characters ‘ “ < and > by replacing them with HTML entities and applying strip_tags - Smarty and Twig provide auto-escape filters :
    • Smarty: {$value.comment|escape:'html':'UTF-8'}
    • Twig:{{value.comment|e}}
  • Limit to the strict minimum the length’s value in database - a database field that allow 10 characters (varchar(10)) is far less dangerous than a field that allows 40+ characters (use cases that can exploit fragmented XSS payloads are very rare)
  • Configure CSP headers (content security policies) by listing external 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 that will be served by your server that 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 warned that you will probably break your frontoffice/backoffice and you will need to preconfigure some bypasses against this set of rules.


Date Action
2023-02-24 Issue discovered during a code review by
2023-02-24 Contact the author who will provide a patch within 4 hours
2023-02-24 V3.0.2 available on and
2023-03-10 Recontact author about the publication of the vulnerability
2023-03-12 Author completes the diff of this present CVE and asks for a delay to publish
2023-05-05 Recontact author about the publication of the vulnerability
2023-05-17 Author ask for another delay before publication
2023-07-15 Recontact author about the publication of the vulnerability
2023-09-17 Recontact author about the publication of the vulnerability
2023-09-30 Recontact author about the publication of the vulnerability
2023-10-30 Inform the author about the publication of the vulnerability
2023-10-30 Request a CVE ID
2023-11-08 Received CVE ID
2023-11-14 Publish this security advisory