🎁 Perplexity PRO offert
Exhaustive report on security protocols and development standards for PrestaShop modules
1. Introduction: the cybersecurity landscape in e-commerce
E-commerce platforms handle high-value data (credentials, payments, customer records) and are prime targets. In PrestaShop, the attack surface depends heavily on module quality: a single vulnerable connector can compromise the whole shop. This report provides a complete security reference for building PrestaShop modules (1.7 and 8), based on official documentation, Marketplace Addons requirements, and community audits (including Friends of Presta). Goal: deliver resilient code against SQL injection, XSS, CSRF, path traversal, and structural flaws.
2. Architecture and structural integrity: first line of defense
2.1 Execution context protection and isolation
Every PHP file must run only through the core dispatcher. Add this guard at the top of every PHP file (classes, helpers, install scripts, PHP views) to block direct access:
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
If _PS_VERSION_ is not defined, the call did not come from PrestaShop; execution stops before any leak or partial run.
2.2 Directory listing prevention
Place an index.php in every directory and subdirectory of the module to prevent file enumeration (including asset folders). Minimal example:
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;
For Apache, add a .htaccess at the module root to deny direct access to templates and config files.
2.3 Dependency hygiene and the PHPUnit case
Third-party libraries can introduce supply chain risks (e.g., accidentally shipping PHPUnit with the vulnerable eval-stdin.php). Good practices:
- Exclude from the production ZIP any test folders (
tests/,spec/), test configs (phpunit.xml), andrequire-devdependencies. - Install in production via
composer install --no-dev --optimize-autoloader. - Keep libraries updated to integrate security fixes.
2.4 Compatibility declaration and lifecycle
Declare compatibility explicitly via ps_versions_compliancy and avoid open-ended bounds:
$this->ps_versions_compliancy = ['min' => '1.7.0.0', 'max' => '8.99.99'];
This protects merchants by blocking installs on unsupported versions.
3. Data validation and sanitization: theory and practice
3.1 Input abstraction with Tools::getValue()
Direct access to $_GET and $_POST is discouraged. Use Tools::getValue($key, $defaultValue) to centralize access, benefit from URL decoding, and avoid undefined indexes. It does not sanitize: follow with strict validation.
3.2 The Validate class: barrier against malformed data
Before any business logic or persistence, apply the right Validate methods:
- Numeric and boolean:
Validate::isInt(),Validate::isUnsignedInt(),Validate::isFloat(),Validate::isBool(). - Strings and HTML:
Validate::isGenericName()for labels,Validate::isCleanHtml()for rich content ($allow_iframeonly when strictly needed). - Specific:
Validate::isFileName()for uploads,Validate::isHookName()for dynamic hooks.
3.3 Path traversal prevention
For any file reference coming from user input, strip path sequences and confine access to the intended folder:
$safeFilename = basename(Tools::getValue('file'));
if (!Validate::isFileName($safeFilename)) {
die('Bad filename');
}
$targetDir = _PS_MODULE_DIR_.'mymodule/uploads/';
if (file_exists($targetDir.$safeFilename)) {
// Allowed processing
}
Using a whitelist of expected files further reduces exposure.
4. Database security: preventing SQL injection
4.1 The Db class and casting
All queries must go through Db (no direct PDO/mysqli). Escape by type:
- Integers: cast
(int)$id. - Strings:
pSQL($name). - SQL identifiers (table/column):
bqSQL($table). - Arrays:
array_map('intval', $ids)orarray_map('pSQL', $values)beforeimplode.
4.2 Securing IN clauses and lists
$ids = Tools::getValue('ids', []);
$safeList = implode(',', array_map('intval', (array) $ids));
$sql = 'SELECT * FROM '._DB_PREFIX_."product WHERE id_product IN ($safeList)";
For string lists, wrap each pSQL value in single quotes.
4.3 Abstraction with DbQuery
Structure queries with DbQuery to reduce risky concatenations and ease audits:
$query = new DbQuery();
$query->select('p.id_product, pl.name');
$query->from('product', 'p');
$query->leftJoin('product_lang', 'pl', 'p.id_product = pl.id_product');
$query->where('pl.id_lang = '.(int) $context->language->id);
$query->where('p.reference = "'.pSQL($ref).'"');
4.4 Prohibited practices
- Never alter core tables (create satellite tables instead).
- Always prefix tables with
_DB_PREFIX_.
5. Output security and XSS prevention
5.1 Smarty escaping modifiers
Each variable in .tpl must be escaped according to context:
- HTML:
{$var|escape:'htmlall':'UTF-8'} - HTML attribute:
{$var|escape:'html':'UTF-8'} - JavaScript:
{$var|escape:'javascript':'UTF-8'} - URL:
{$var|escape:'url'}
5.2 The nofilter controversy
{$content nofilter} disables XSS protections. Use it only on HTML validated upstream with Validate::isCleanHtml(). Never apply it to raw user input (Tools::getValue).
6. Authentication, authorization, and CSRF protection
6.1 Cross-Site Request Forgery (CSRF)
6.1.1 Back Office (Admin)
- Generation:
Tools::getAdminTokenLite('AdminMyController'). - Explicit validation for custom actions or AJAX:
if (!Tools::isSubmit('submitAction') || Tools::getValue('token') !== Tools::getAdminTokenLite('AdminMyController')) {
die('Forbidden');
}
Links generated via Context::getContext()->link->getAdminLink(...) include the token automatically.
6.1.2 Front Office
- Generation:
Tools::getToken()(session-bound). - Validate server-side before any processing.
- In
ModuleFrontController, set$this->ssl = true;to force HTTPS and protect token transport.
6.2 Password hashing evolution
PrestaShop 1.7/8 uses bcrypt through core services (PrestaShop\PrestaShop\Core\Crypto\Hashing). For modules handling authentication, support verification of legacy MD5 hashes during migration, then rehash to bcrypt on successful login.
7. Modernization and PrestaShop 8 standards
7.1 Strict typing and PHP rigor
PrestaShop 8 supports PHP 8.0/8.1: respect method signatures (parameter and return types) when overriding the core, and favor declare(strict_types=1); to reduce implicit behaviors.
7.2 Service-oriented architecture (Symfony)
Declare controllers as services (config/services.yml) and inject dependencies (repositories, translator, logger) instead of static calls. This improves testability and lets you apply Symfony security policies.
7.3 Removal of deprecated features
Legacy APIs removed in 8 require an audit of deprecated calls before migration. Replace direct database or file access with modern services.
8. Quality assurance and validation tools
8.1 PrestaShop Validator
Always submit the module to validator.prestashop.com: it detects structural errors, forbidden PHP functions (eval, shell_exec), Smarty escaping issues, and licensing problems.
8.2 PHPStan: advanced static analysis
Integrate prestashop/php-dev-tools and PHPStan into CI to catch type errors, missing methods, and dead branches before runtime.
8.3 Threat intelligence: Friends of Presta
Follow security advisories from Friends of Presta to anticipate attack patterns seen in the wild (SQLi via Tools::getValue, path traversal, etc.) and patch modules promptly.
Conclusion
Securing a PrestaShop module requires defense in depth: structural guards (index.php, .htaccess), strict validation and sanitization (Tools, Validate, pSQL), safe output (Smarty escaping), anti-CSRF mechanisms, and adoption of modern PrestaShop 8 standards. Coupled with audit tools (Validator, PHPStan) and active monitoring, developers can ship robust modules that protect merchants and customers against current threats.
Articles Liés
Fini le café devant Excel : Votre "Daily Merchant Morning" 100% automatisé avec PrestaShop et l'IA 🚀
Découvrez comment transformer votre routine matinale e-commerce en recevant chaque matin un briefing stratégique comp...
Rapport exhaustif sur les protocoles de sécurité et les standards de développement pour les modules PrestaShop
Référentiel complet pour concevoir des modules PrestaShop 1.7 et 8 durcis contre SQLi, XSS, CSRF et traversées de rép...
Rétrospective Complète des Événements PrestaShop 2025
Je vous propose un résumé complet de tous les événements majeurs de PrestaShop en 2025, une année exceptionnelle marq...
La Grande Guerre des IA de 2025 : Chronique d'une Révolution qui Redéfinit le E-commerce et le Travail
L'année 2025 restera dans l'histoire comme le tournant décisif de l'intelligence artificielle générative. GPT-5, Gemi...
Rigueur du Code vs Chaos de l'IA : Faut-il réinventer nos standards PHP pour les marchands PrestaShop ?
L'arrivée de l'IA dans l'écosystème PrestaShop bouscule nos certitudes de développeurs. Faut-il sacrifier la rigueur ...
Arrêtez de réinventer la roue : 5 pépites cachées dans le fichier Tools.php de PrestaShop
Vous pensez que le "Clean Code" est la seule voie ? Détrompez-vous. Parfois, l'efficacité brutale se cache dans les v...
Découvrez mes autres articles
Guides e-commerce, tutoriels PrestaShop et bonnes pratiques pour développeurs
Voir tous les articles