Prestashop : Attention, vos templates sont facilement copiables

Pour personnaliser votre boutique Prestashop, vous avez besoin de créer ou d’acheter un thème. Ces thèmes sont plus communément appelés « templates ».
Pour traiter le code de ces thèmes, Prestashop utilise un moteur de template : Smarty, qui est aussi utilisé dans de nombreux autres CMS ou applications. (Plici, Pligg, Joomla, WordPress avec un plugin, etc…).
Le problème que nous souhaitons décrire aujourd’hui est qu’un template Prestashop peut être copié, pillé, volé, en quelques secondes.
Nous allons donc voir comment protéger votre template ou thème Prestashop.
La procédure décrite ci-dessous est à exécuter à vos risques et périls. Nous ne pourrons en aucun cas être tenu pour responsable, si votre boutique ne fonctionne plus, ou votre thème ne s’affiche plus. Pensez à faire une sauvegarde des fichiers que vous allez modifier.

Sommaire

1. Comment peut-on vous voler votre template ou thème Prestashop ?

Nous allons dans un premier temps expliquer où se situe le problème dans l’utilisation de Smarty par Prestashop.
Il faut savoir que n’importe quel CMS qui utiliserait Smarty de la façon dont l’utilise Prestashop aurait ce problème. Ce n’est donc ni une faille de Smarty, ni de Prestashop. C’est juste une utilisation maladroite.
Pour afficher le code html de votre thème, Smarty compile les différents fichiers provenant de votre template. Ces fichiers peuvent être des fichiers ayant l’extension « .tpl », « .php » ou autres.
C’est ici que le problème se situe. Prestashop utilise des templates à base de fichiers ayant l’extension « .tpl ».

En quoi est-ce un problème ?

Lorsque l’on tente d’accéder directement à un fichier avec l’extension « .tpl », son contenu est affiché en « clair ».
Avec le code de Prestashop, nous savons que dans un thème, il y a des fichiers obligatoires pour afficher le thème de la boutique (à moins d’avoir changé plusieurs parties du code Prestashop, ce qui semble compliqué). Nous savons donc que Prestashop appellera les fichiers :  « index.tpl », « header.tpl », « footer.tpl », « 404.tpl » etc.
Nous allons prendre un exemple concret, notre équipe possède une boutique tournant sous Prestashop https://www.magavenue.com/
Nous savons que les fichiers de styles (css), permettants de styliser le thème, se situent dans un sous dossier du thème (dossier /css/). Il en est de même pour les images relatives au thème, ou pour les fichiers javascript.
Il suffit donc d’afficher la source de notre boutique (avec n’importe quel navigateur), de chercher la ligne indiquant l’adresse du fichier css à charger et nous avons l’adresse où se trouve le thème utilisé par notre boutique. (Nous aurions pu faire de même avec une image par exemple).
Si nous affichons la source de notre boutique nous avons, au tout début du code, la ligne suivante :

<link href= »/themes/magavenue/css/global.css » rel= »stylesheet » type= »text/css » media= »all » />

Nous savons donc maintenant que notre thème Prestashop se trouve à l’adresse : https://www.magavenue.com/themes/magavenue/
Une fois celle-ci obtenu, rien de plus simple pour récupérer les fichiers du thème de notre boutique. Il suffit de rajouter les différents noms de fichiers à la suite de cette adresse.
Par exemple :

https://www.magavenue.com/themes/magavenue/404.tpl
https://www.magavenue.com/themes/magavenue/header.tpl
https://www.magavenue.com/themes/magavenue/footer.tpl

Il ne nous reste plus qu’à récupérer les fichiers css, javascript, et les différents fichiers images. Qui eux seront toujours diffusés en clair.
En quelques minutes, vous aurez récupéré un thème complet Prestashop.

Quelles différences entre récupérer les fichiers .tpl d’une boutique Prestashop et accéder au source directement ?

Si vous accèder à une boutique Prestashop et que vous affichez la source la page, vous ne verrez que le code compilé du thème, c’est à dire de l’html. Mais il sera très dur, de pouvoir l’assembler de sorte à obtenir le thème utilisable sur une autre boutique. Alors qu’en récupérant les fichiers .tpl, vous obtenez un thème complet que vous pourrez mettre en place sur une boutique Prestashop, pour générer le code html facilement.

2. Se protéger simplement du vol de votre thème Prestashop par un .htaccess

Une première façon d’empêcher le vol de votre template Prestashop est d’utiliser un fichier .htaccess.
En effet si quelqu’un essai d’accéder directement aux différents fichiers .tpl comme nous l’avons montré précédemment, il sera redirigé vers une autre page (l’index de votre site par exemple).
Pour faire cela, vous devez créer un fichier .htaccess dans le dossier de votre thème puis y rentrer le code suivant :

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^https://magavenue.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^https://magavenue.com/$ [NC]
RewriteCond %{HTTP_REFERER} !^https://www.magavenue.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^https://www.magavenue.com$ [NC]
RewriteRule .*\.(jpg|jpeg|gif|png|bmp|swf|tpl|css)$ https://www.magavenue.com/ [R,NC]

Vous aurez bien entendu compris, qu’il faudra remplacer https://www.magavenue.com/ par l’adresse de votre boutique.
Si les images, ou le thème de votre boutique Prestashop ne s’affichent plus, c’est que vous avez sûrement entré une mauvaise adresse à cette étape.

Le .htaccess n’est pas fiable, et votre template Prestashop peut toujours être volé.

Vous avez mis en place une première barrière de protection. Si nous essayons d’accéder directement à un fichier de votre thème, nous serons rediriger vers l’index de votre boutique.
Néanmoins le problème n’est pas résolu pour autant, cette protection peut se contourner facilement, il faut donc arriver à protéger les fichiers .tpl de l’affichage.

3. Comment protéger son thème ou template Prestashop de l’affichage

Comme nous l’avions expliqué dans la première partie, le problème que nous mettons en évidence, vient du fait que les fichiers des templates Prestashop sont à la base des fichiers .tpl qui s’affichent en clair. Il faudrait donc arriver à faire en sorte que si nous accédons au fichier, celui-ci ne soit pas considéré comme un simple fichier « texte », mais soit exécuté par le serveur sur lequel il se trouve.
Plus clairement il faudrait donc que les fichiers du template soit des fichiers avec l’extension « .php », afin que ceux-ci ne puissent être affichés directement, mais exécutés.
Pour protéger notre thème Prestashop du vol, nous allons donc modifier tout nos fichiers contenu dans le dossier de notre thème. En changeant leurs extensions de « .tpl » à « .php ». Il existe déjà un fichier index.php, permettant de rediriger l’utilisateur accédant directement au dossier de votre template. Vous devez donc le supprimer pour pouvoir renommer le fichier index.tpl en index.php. Le .htaccess redirigeant déjà l’utilisateur.
Si l’on accède à un fichier .php ne contenant pas de php, celui-ci affichera le code du template malgré tout.
En effet si nous accédons directement à un fichier .tpl, renommé en .php, nous aurons toujours accès à la source du template.
Il faut donc que le code s’exécute en tant que du code PHP.
Nous allons donc ajouter en haut de chaque fichier « .tpl » le code suivant :

{if $magavenueblog ==1}
<?
{/if}

Que fait ce code ?

Si nous accédons à un fichier directement contenant ce code, la partie « {if $magavenueblog ==1} » sera traité comme du texte pur et simple, il ne sera donc pas interprété comme du PHP.
Par contre à partir du moment, où l’interpréteur tombera sur le « <? », le fichier sera interprété comme du PHP, et une erreur se produira. En effet le code « {/if} » n’est pas une instruction valide en PHP. Il ne sera donc plus possible d’afficher directement le code du template.
Par contre, si nous somme dans le cadre de l’utilisation du template par Prestashop et donc Smarty, au moment ou l’interpréteur arrivera sur « {if $magavenueblog ==1} », il cherchera s’il existe dans le thème une variable $magavenueblog. Celle-ci n’existant pas il n’affichera pas le « <? ». L’affichage du template pourra alors se dérouler correctement, sans que le code ajouté ne pose problème.

Comment modifier Prestashop pour qu’il prenne en compte les fichier .php au lieu des .tpl ?

Le problème principal pour sécuriser les templates, était de pouvoir facilement modifier Prestashop pour prendre en compte les templates avec des fichiers .php au lieu des fichiers .tpl.
En effet dans chaque page de votre boutique, vous avez des fonctions Smarty appelant les fichiers .tpl. Il serait donc très long de tous les modifier un par un, de ne pas en oublier, et de refaire cela à chaque mise à jour.
Il faut donc intercepter la fonction entre Prestashop et Smarty appelant les fichiers, afin de rediriger les requêtes d’un fichier .tpl vers un fichier .php.

Dois-je modifier les fichiers .tpl contenus dans les modules Prestashop et autres ?

Un autre problème dans notre solution, est qu’il faut dans un premier temps modifier tous les fichiers .tpl de notre thème en fichier .php. Mais il faudrait alors aussi modifier tous les fichiers .tpl contenu dans les modules, le faire à chaque fois que l’on installe un nouveau module. Bref cela semble aussi très compliqué à mettre en place.
Nous allons donc dans notre redirection de requête mettre en place une condition. Celle-ci testera si un fichier .tpl existe, et sinon appellera un fichier .php.
Ainsi, si les fichiers de votre thème, sont des .php, Prestashop les prendra en compte, mais il prendra aussi en compte, les fichiers .tpl contenu dans les modules, sans que vous ayez besoin de les renommer.

Comment réaliser la redirection Smarty ?

Il faut modifier le fichier Smarty.class.php contenu dans le dossier /tools/smarty/ de votre boutique Prestashop.
A la ligne 1106, il faut modifier la fonction display et y ajouter :

if (!file_exists($resource_name))
$resource_name=substr($resource_name, 0, -4).’.php’;

Avant :

function display($resource_name, $cache_id = null, $compile_id = null)
{
$this->currentTemplate = substr(basename($resource_name), 0, -4);
$this->fetch($resource_name, $cache_id, $compile_id, true);
}

Après

function display($resource_name, $cache_id = null, $compile_id = null)
{
if (!file_exists($resource_name))
$resource_name=substr($resource_name, 0, -4).’.php’;
$this->currentTemplate = substr(basename($resource_name), 0, -4);
$this->fetch($resource_name, $cache_id, $compile_id, true);
}

Il faut ensuite modifier la fonction fetch à la ligne 1123 et y ajouter :

if (!file_exists($resource_name))
$resource_name=substr($resource_name, 0, -4).’.php’;

Avant :

function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
{
static $_cache_info = array();
$_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
? $this->error_reporting : error_reporting() & ~E_NOTICE);
[…]

Après :

function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
{
static $_cache_info = array();
if (!file_exists($resource_name))
$resource_name=substr($resource_name, 0, -4).’.php’;
$_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
? $this->error_reporting : error_reporting() & ~E_NOTICE);
[…]

Et enfin la fonction _smarty_include à la ligne 1854 et y ajouter :

if (!file_exists($params[‘smarty_include_tpl_file’]))
$params[‘smarty_include_tpl_file’]=substr($params[‘smarty_include_tpl_file’], 0, -4).’.php’;

Avant :

function _smarty_include($params)
{
$backup = $this->currentTemplate;
$this->currentTemplate = substr(basename($params[‘smarty_include_tpl_file’]), 0, -4);
[…]

Après :

function _smarty_include($params)
{
$backup = $this->currentTemplate;
if (!file_exists($params[‘smarty_include_tpl_file’]))
$params[‘smarty_include_tpl_file’]=substr($params[‘smarty_include_tpl_file’], 0, -4).’.php’;
$this->currentTemplate = substr(basename($params[‘smarty_include_tpl_file’]), 0, -4);
[…]

Votre template est donc protégé du problème mis en évidence précédemment.
Conscient que la démarche décrite est compliquée, nous pouvons exécuter la procédure pour vous. Vous pouvez commander cette prestation sur notre boutique.

4. Autre solution

Une autre solution, pourrait être de déplacer les dossiers contenant les templates, dans une partie du serveur n’étant pas accessible par Internet. Mais cela peut être fait seulement par les personnes ayant un serveur capable de faire cela (par exemple, un serveur dédié). Il faudra alors modifier le fichier de configuration de Smarty, et lui donner l’adresse du dossier pour accéder au thème.

5. Conclusion

Ces solutions permettent de protéger efficacement votre template ou thème de votre boutique, du problème que nous avons mis en évidence.
Il faut néanmoins savoir que cela ne signifie pas que votre template est complétement sécurisé. Vous ne serez pas protégé si vous avez :

  • une faille dans votre serveur
  • fait une erreur
  • ou s’il existe un problème pas encore mis à jour.

41 commentaires sur “Prestashop : Attention, vos templates sont facilement copiables”

  1. Merci pour l’info.
    Pour la solution, en revanche, il suffit d’un petit .htaccess dans le répertoire /themes/ de votre boutique, et le problème est réglé en 30s :

    <FilesMatch "\.tpl$">
    Deny from all
    </FilesMatch>

  2. Merci pour votre retour. Comme dit plus dans l’article, le .htaccess permet une première couche de protection. Après cela se contourne aisément… D’où la seconde sécurité.
    (on ne s’est pas entêté à trouver une solution pendant des heures pour rien :p).

  3. Les tags laissé par défaut par presta genre  » , un minimum d’étude permet de mieux récupérer le template. Exemple plus rapide j’observais votre article, dans le mien comme j’expliquais le plus facile est d’afficher l’image 😉 mais cependant, il existe déja des outils (très simple comme httracks bien configuré ou un intellitamper bien retravaillé) qui peuvent copié ! Les russes ont déja même un apli qui copie direct et contourne le htacces :p (netscann peut casser d’ailleurs le htacess). Now disons que la template est sécurisé au max, il reste éventuellement le cache qui permettra de récupérer une partie de la source, mais le dernier risque c’est le code source! Car ds presta, il faut principalement les fichiers header et footer, le reste peut se reconstituer facilement ! Donc un malin et la j’en viens au tag va renifler (après avoir copier le site) l’endroit genre «  » et «  » ce sont principalement les parties les plus importantes!!! La solution oui, il faut crypter mais le tout en finesse sans casser le référencement et arriver a faire la compilation par smarty, (mais pour cette solution, je écrirai un article rapidement 😉 ) et il ne reste plus rien au pirate!!! Voili voila 🙂 Cordialement

  4. Je ne pense pas que crypter un thème soit nécessaire. D’une part pour toutes les contreparties que cela implique, et cela ne protégera pas plus…
    Si comme vous dites, quelqu’un est au point de récupérer le code-source, pour le transposer en .tpl, c’est qu’il a un minimun de connaissances…
    Donc il serait tout à fait capable de faire pareil avec le simple visuel de votre thème, sans code…
    A la limite la solution serait de ne pas faire de thème… plus de soucis au moins !

  5. Non pas d’accord :p lol, car le crytage va ralentir le copieur et le décourager :p De plus, si tu ne peux pas prendre dans le cache, ne peut pas enregistrer la page et que si le javascript est désactiver(impossible de voir la page), la à part l’imprim écran (qui peut se bloquer aussi aujourd’hui), la moi je sais plus quoi faire :p lol 😉

  6. Encore faut il pouvoir prouver la copie et le vol. A moins que le thème soit exactement le même… De plus, le copyright étant sans formalités, comment prouver que votre design est plus ancien que celui du copieur.
    Un procès n’est pas non plus forcément une chose simple à mettre en oeuvre. Et si jamais le pilleur se situe dans un autre pays…
    Veille concurrentielle, plus facile à dire qu’à faire. Vous regardez peut être les boutiques de vos concurrents directs, mais est-ce que vous regardez les boutiques de tous les genres, de tous les pays ?

  7. Bonjour,
    Sympa pour la technique, mais vous faites quoi du droit d’auteur et de la propriété intellectuelle ?
    Si une personne vous vole un template il faut :
    – l’inviter à retirer le template de sa boutique
    – la relancer en cas de non-réponse
    – lui rappeler qu’une atteinte aux droits d’auteur c’est 300 000€ et de la prison si ça doit se finir devant la justice.
    De toute manière même avec ces protections vous n’êtes pas à l’abri d’un vol, même s’il est vrai que ça va déjà beaucoup freiner la démarche.
    Encore merci tout de même.

  8. Bonjour,
    Pourquoi ne pas simplement spécifier à apache de parser les fichiers .tpl (ce qui au final reviendrait au même que de renommer avec l’extension .php)
    => dans un .htaccess :
    AddType application/x-httpd-php .tpl
    A tester / adapter selon la config. serveur, mais la solution me parait bien plus simple à implémenter?!

  9. Bonjour, juste une précision concernant le point 4 :
    La plupart des hébergeurs proposant des serveurs mutualisés propose également une arborescence hors web. C’est le cas d’OVH notamment.
    D’ailleurs pour des questions de sécurité il pourrait être intéressant de mettre dans cette arborescence hors web l’ensemble des fichiers de prestashop, à part bien-entendu les fichiers appelant les contrôleurs (fichier php à la racine) et les fichiers css/js des thèmes.
    Je trouve ce post est intéressant dans le sens où il met en exergue le manque de sécurité de ce genre de CMS, plus que dans la protection du copyright. En effet, j’estime que ce sont plutôt les images qui encourent des risques d’utilisation frauduleuse et contre cela il n’y a rien à faire.

  10. Pas très bien compris le tuto. Je connais pas bien prestashop mais je connais bien Smarty.
    Le client n’a à priori pas besoin d’accéder aux .tpl donc empecher d’y accéder via un .htaccess (complètement, meme pas de check du referer).
    Pour les images et css de toutes façons vous pourrez toujours vous faire voler. On peut compresser le css pour mettre des batons dans les roues.

  11. @poulpillusion : ‘Deny from all’ empêchera l’affichage du template tout simplement.
    Personnellement j’ai choisi un htaccess :
    deny from all
    allow from localhost
    Impossible d’accéder au dossier ou aux fichiers et prestashop continue de les lire et peut afficher son template comme avant 😉

  12. @VitamineSeb : d’où les directives FilesMatch (qui avait sauté dans mon premier commentaire)
    Elles permettent de n’interdire l’accès qu’aux fichiers .tpl, qui sont de toute facon chargés uniquement par Smarty, et jamais par une requête HTTP. Ils ne doivent donc jamais être services par Apache, et c’est ce à quoi servent ces directives. Elles ont d’ailleurs été intégrées dans la version de dev de prestashop (cf. fichier themes/.htaccess), mais pas encore dans les releases stable.
    Par ailleurs, je pense que ton « Allow from localhost » ne sert à rien sur un site en production, et risque de t’induire en erreur si tu développes sur une version locale.

  13. @poulpillusion
    En production ou en dev, localhost signifie la même chose: le poste sur lequel est exécuté le script… donc en production il s’agit du serveur lui même, je ne vois pas où il y a confusion?

  14. @Cédric la confusion vient du fait que ce n’est pas le serveur qui fait les requêtes HTTP mais le client.
    Si tu héberges la version de dev sur ta machine, le client et le serveur correspondront à la même machine. Ainsi, un « Allow from localhost » t’ouvre bien l’accès aux ressources.
    En revanche, si tu navigues sur le site en production, le client c’est ton PC, et le serveur c’est une autre machine, dans un datacenter. Il s’agit alors de 2 machines différentes.
    Ainsi ton « Allow from localhost » que tu mets dans ton .htaccess autorise le serveur a se faire des requetes HTTP à lui même… ce qui est d’un intérêt limité (puisque je le répète, c’est le client qui fait les requêtes HTTP).

  15. Bonjour et bravo pour ce POST.
    Pour pallier au pillage des *.tpl (je ne savais pas que c’était possible d’ailleurs) j’ai installé tous les dossiers de classes et de templates en dehors du /www/ répertoire public du serveur. Il semblerait que ça marche. Le serveur que j’utilise est un mutualisé chez OVH.

  16. J’ai installer le prestashop aussi ses modules. je veux modifier des choses au templete prenant l’exemple de fabriquant je veux le renommer Entreneurs est ce que je peux et si oui comment ???
    merci d’avance.

  17. Y a t’il une solution pour identifier tous les fichiers .tpl du thème ?
    Car footer, header etc.. ok ce sont des communs, mais pour les autres comment les identifier?
    Bonne technique 😉

  18. preview.jpg
    Image utilisé pour voir un aperçu de votre theme.
    404.tpl
    Page affichée lorsqu’une page demandée par l’utilisateur n’a pas été trouvée.
    address.tpl
    Page affichée qui propose ç l’utilisateur d’ajouter ou de modifier son adresse.
    addresses.tpl
    Page qui liste toutes les adresses du client.
    authentication.tpl
    Page login de l’utilisateur.
    best-sales.tpl
    Page qui liste les meilleurs ventes.
    breadcrumb.tpl
    Fil d’Ariane de navigation
    category.tpl
    Page qui liste les produits d’une catégorie
    category-tree-branch.tpl
    Utilisé uniquement pour le bloc Catégories.
    category-cms-tree-branch.tpl
    Utilisé uniquement pour le bloc Catégories.
    cms.tpl
    Pages informatives (onglet « Outil » > « CMS » du back-office).
    contact-form.tpl
    Formulaire de contact
    discount.tpl
    Affiche les bons de réduction de l’utilisateur.
    errors.tpl
    Affiche les erreurs. Cette page est présente sur toutes les pages.
    footer.tpl
    Pied de page.
    guest-tracking.tpl
    Cette page est utilisée lorsque l’utilisateur n’a pas de compte sur le site
    header.tpl
    En-tête de page.
    history.tpl
    Page affichant les commandes d’un utilisateur.
    identity.tpl
    Page proposant de changer les informations d’un utilisateur.
    index.php
    Page blanche, propose aux utilisateurs de voir le contenu du dossier.
    index.tpl
    Page d’accueil.
    maintenance.tpl
    Page de maintenance.
    manufacturer.tpl
    Page qui liste les fabricants.
    manufacturer-list.tpl
    Page qui liste les articles d’un fabiquant.
    my-account.tpl
    Page d’accueil du compte d’un utilisateur.
    new-products.tpl
    Affiche les derniers produits ajoutés sur le site
    order-address.tpl
    Page du processus de commande : Étape 1 – choix des adresses (livraison, facturation).
    order-carrier.tpl
    Page du processus de commande : Étape 2 – choix du mode de livraison.
    order-confirmation.tpl
    Page de confirmation de commande (après paiement).
    order-detail.tpl
    Affiche le détail d’une commande de l’utilisateur.
    order-follow.tpl
    Affiche la page de demande de retour produit d’un utilisateur.
    order-payment.tpl
    Page du processus de commande : Étape 3 – choix du mode de paiement.
    order-return.tpl
    Page de détails d’un retour client.
    order-slip.tpl
    Page listant les avoirs d’un utilisateur.
    order-steps.tpl
    Barre d’évolution du processus de commande.
    pagination.tpl
    Page de pagination.
    password.tpl
    Propose de changer le mot de passe d’un utilisateur.
    prices-drop.tpl
    Affiche les promotions.
    product.tpl
    Détail un produit.
    product-list.tpl
    Liste de produits.
    product-sort.tpl
    Menu permettant de filtrer une liste de produits.
    search.tpl
    Page listant les résultats d’une recherche.
    shopping-cart.tpl
    Panier de l’utilisateur.
    shopping-cart-product-line.tpl
    Page de détail d’une ligne du panier.
    sitemap.tpl
    Plan du site.
    supplier.tpl
    Affiche les produits d’un fournisseur.
    supplier-list.tpl
    Affiche les fournisseurs.
    thickbox.tpl
    Page de zoom d’une photo d’un produit.
    De rien.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *