Unauthenticated Blind SQL Injection Vulnerability In PEEL Shopping


Unauthenticated Blind SQL Injection Vulnerability In PEEL Shopping

Advisory ID



PEEL Shopping

Vulnerable Version


Fixed Version



Discovery Date

10 July 2021


Mohammad Faisal Sammio | NetbyteSEC

Vendor/product description:

"PEEL SHOPPING is a free ecommerce CMS in PHP / MySQL, that is to say a a modern and safety management tool that lets you manage your product catalog, the text on your website and everything else from a single, simple and efficient administrative interface. Since 2004, PEEL brings innovation and reliability to the world of e-commerce by offering tailored solutions to create complete and simple online shops at suitable prices for everyone."

Source : https://www.peel-shopping.com/

Vulnerability overview:

PEEL Shopping version 9.4.0 allows remote SQL injection. A public user/guest (unauthenticated) can inject a malicious SQL query in order to affect the execution of predefined SQL commands. Upon a successful SQL injection attack, an attacker can read sensitive data from the database and possibly modify database data.

Technical details:

There are three (3) files associated with the vulnerability as mentioned in technical details below. The files are produit_details.php, fonctions.php and configuration.inc.php. This section will explain the details through the simplest point in a way.


    Figure 1: produit_details.php

  • line 22 - product_infos initialized an array() function to hold product info values

  • id parameter without sanitization

    Figure 2: id parameter without sanitization

  • line 55 - product_infos request input (user-controlled) via id parameter without being sanitized to be passed into arguments of get_product_infos() function.

    **Since id is a type of integer, the proper sanitization method would be intval()

  • get_product_infos function

    Figure 3: get_product_infos function

  • line 8014 - get_product_infos() function is used to retrieve raw product information, where the argument $where is holding id value that is passed from var product_infos in (line 55, figure 2)

  • file fonctions.php

    Figure 4: file fonctions.php

  • line 8091 - check if $where is an array or not - return False

  • line 8093 - check if $where IS NOT number or a numeric string - return False

  • line 8095 - else, set $sql_cond_array[] = p.id = '$id'

  • line 8098 - Based on (line 8014, figure 3) the $filter_site_cond is TRUE, so $sql_cond_array will having get_filter_site_cond() function passing 4 arguments as stated in figure 4

  • get_filter_site_cond function

    Figure 5: get_filter_site_cond function

  • line 5553 - The $table_technical_code is storing 'produits' as its value (refer line 8099, figure 4), while $table_alias as 'p'

  • line 5554 - Since $table_technical_code == 'produits' which is NOT EMPTY, then $field will be 'site_id'

  • line 5554 - Since $table_technical_code == 'produits' which is NOT EMPTY, then $field will be 'site_id'

  • get_filter_site_cond

    Figure 6: get_filter_site_cond

  • line 5637 - The $exclude_public_items is FALSE (refer line 5553, figure 5), else go to line 5645

  • line 5645 - In short, $use_set is FALSE, so $cond_array[] will be p.site_id IN ('0','1') - where $prefix = p. , $field = site_id and $site_id = '1' (refer line 216, figure 7).

  • $GLOBALS['site_id'] = 1

    Figure 7: $GLOBALS['site_id'] = 1

    Figure 7 shows the value of $site_id which is 1

    SQL query

    Figure 8: SQL query

  • line 8104 - For now, the sql query will be ( SELECT p.* FROM peel_produits p WHERE p.id = '$id'p.site_id IN ('0','1') ORDER BY $order_by LIMIT $limit ) where $sql_fields = 'p.*'

  • line 8107 - There is an implode() function that will join array elements with a string of " AND ". As we know, $sql_cond_array is storing p.id = '$id'p.site_id IN ('0','1') as its value.

  • Then, the output after implode() will be p.id = '$id' AND p.site_id IN ('0','1')

    Since $order_by = null and $limit = 1 (refer line 8014, figure 3),

    The final query will be :

    • ( SELECT p.* FROM peel_produits p WHERE p.id = '$id' AND p.site_id IN ('0','1') LIMIT 1 )

    For example:

    Payload: '12' OR (SELECT * FROM (SELECT(SLEEP(5)))NBSX)

    will work in the query as "WHERE" clause is the injection point:

    • ( SELECT p.* FROM peel_produits p WHERE p.id = '12' OR (SELECT * FROM (SELECT(SLEEP(5)))NBSX) AND p.site_id IN ('0','1') LIMIT 1 )

    When the query is executed, it will select all data from table peel_produits by id equal to 12 and it will sleep for 5 seconds before showing the data.

Proof Of Concept:

The following concept could be used to perform a blind SQL injection attack:


    PARAMETER : id


    URL : http://$HOST/achat/produit_details.php?id=[SQL-INJECTION]

  • As a proof of concept for exploiting the blind SQL injection, requesting the following URL will cause a time delay.

  • http://$HOST/achat/produit_details.php?id=(SELECT * FROM (SELECT(SLEEP(5)))NBSX)

  • Delay in server response time per request respectively

    Figure 9: Delay in server response time per request respectively

Tested Versions:

The vulnerability has been verified to exist in the PEEL Shopping version 9.4.0. It was found in this version, which was updated and released below a week just prior to the discovery.

Vendor Contact Timeline:

2021-07-10: Contact vendor through email.

2021-07-12: Request update from vendor, sending advisory draft and proof of concept.

2021-07-13: Vendor response with acknowledgement and confirms security issue.

2021-07-14: Vendor releases security patches available on their website.

2021-07-26: Public release of security advisory


Update to the latest version on their website.

Link: https://www.peel-shopping.com/modules/telechargement/telecharger.php?id=7