La CI PrestaShop pour les modules ne peut plus se limiter à « exécuter PHPUnit et zipper le dossier ». Sur une boutique en production, un module est du code arbitraire avec des droits applicatifs élevés (hooks, overrides éventuels, accès DB via Db, accès FS, HTTP sortant, webservices…). Et côté cœur PrestaShop, l’installation d’un module (ZIP) n’implique aucune vérification cryptographique (signature, provenance, intégrité) : si un ZIP est altéré en transit, ou si une dépendance Composer/NPM est compromise, le backoffice l’installera et l’exécutera.
Le risque n’est pas théorique : il suffit d’un module très répandu qui embarque une dépendance vulnérable, ou d’une release reconstruite « à la main » avec un vendor/ différent du tag Git. L’incident devient alors ingérable (audit post-mortem impossible, impossibilité de prouver ce qui a été déployé, MTTR qui explose). Pour mémoire, même un module officiel peut être affecté par une faille et imposer un cycle de patch en urgence (exemple : pscheckout et CVE, voir l’article interne : https://www.expertise-prestashop.fr/2026/06/04/cve-2025-61922-pscheckout-mise-a-jour-5-0-5-et-mesures/).
Dans la pratique (et particulièrement en contexte agence / TMA / e-commerce en France et en UE), la question revient souvent sous une forme très opérationnelle : “qu’est-ce qui est exactement en production, et d’où ça vient ?” Entre les téléchargements manuels, les ZIP envoyés par e-mail, les hotfix non taggés, et les environnements de préprod non alignés, la traçabilité disparaît vite.
Dans cette optique, une CI « moderne » doit produire trois artefacts exploitables :
- une attestation de provenance (qui a construit quoi, avec quel commit, quel runner, quel workflow),
- un SBOM (Software Bill of Materials : inventaire machine-readable des composants et versions),
- une validation automatique orientée PrestaShop (installation, compatibilité versions, tests, analyse statique, scan de vulnérabilités et licences).
Un moyen simple de rendre tout ça actionnable est de formaliser (dès le README du module) ce qui est livré à chaque release. Exemple de “contrat de release” minimal :
module.zip(artefact installable)sbom-php.json+sbom-js.json(ou fusionnés)provenance/ attestation (SLSA/GitHub Attestations)- un changelog (humain) + une note sécurité si pertinent
Les sections suivantes partent d’un cas réaliste : développement de module pour PrestaShop 8.1+ et 9.x, sur PHP 8.2/8.3 (PrestaShop 9.1 supporte PHP 8.1–8.5 : https://www.expertise-prestashop.fr/2026/03/24/prestashop-9-1-compatibilite-php-8-1-8-5-cli-et-nouveautes-developpeurs/). Les exemples CI utilisent GitHub Actions, mais les mêmes primitives existent sur GitLab CI.
Table des matières :
- Provenance en CI : attester la chaîne de build (SLSA), signer, et arrêter de « faire confiance » au ZIP
- SBOM module PrestaShop : formats (CycloneDX/SPDX), génération Composer/NPM, et exploitation vulnérabilités/licences
- Validation automatique des modules : installer/désinstaller en environnement jetable, matrice PS/PHP, et QA de code
- Garde-fous de release : policy-as-code, seuils de sécurité, et traçabilité exploitable en production
Provenance en CI : attester la chaîne de build (SLSA), signer, et arrêter de « faire confiance » au ZIP
La provenance, au sens supply chain, sert à répondre à une question simple : comment cet artefact a été produit, à partir de quel code source, avec quelles dépendances, et par quel pipeline. SLSA (Supply-chain Levels for Software Artifacts) formalise ce besoin et donne un cadre pour renforcer l’intégrité de la chaîne de build (référence : https://slsa.dev/). Pour un module PrestaShop, ça se traduit par une exigence non négociable : la release doit être reconstruisible et rattachable à un commit, sinon vous ne pouvez ni auditer ni prouver.
Rendre un ZIP réellement “reproductible” (pas juste “rebuildable”)
Le point dur, c’est que les builds « artisanaux » ne sont pas déterministes : timestamps des fichiers, ordre d’archivage, dépendances téléchargées sans verrouillage strict, npm install sans lock, génération d’assets non stable… Si vous avez déjà dû comparer deux ZIP censés être identiques (mais dont le hash diffère), vous avez vu le problème.
Une approche pragmatique consiste à :
- Imposer des lockfiles :
composer.locketpackage-lock.json/pnpm-lock.yaml. - Éviter les dépendances “flottantes” : pas de contraintes trop larges qui autorisent des résolutions différentes à date.
- Fixer une base temporelle :
SOURCE_DATE_EPOCH(souvent le timestamp du commit). - Contrôler l’archivage :
zip -X(sans attributs extra), et exclure les dossiers non livrables. - Stabiliser la toolchain : versions de PHP/Node, et idéalement container de build verrouillé.
- Ne pas embarquer le hasard : minimiser les étapes qui génèrent des fichiers non déterministes (ex. banners avec date/heure).
Si vous construisez dans des images Docker, verrouillez aussi la couche build avec BuildKit (voir l’article interne sur le build reproductible : https://www.expertise-prestashop.fr/2026/06/24/integration-continue-prestashop-buildkit-github-actions-et-build-reproductible/).
Mini-scénario (classique) : un client “urgent prod” récupère un ZIP depuis un canal non standard (messagerie, outil de ticketing) et l’installe. Deux semaines après, vous recevez des logs d’erreurs et un ZIP “tel qu’installé”… mais vous n’arrivez pas à le faire matcher avec le tag Git correspondant. Sans build déterministe + provenance, votre analyse se limite à “comparaison de dossiers” et hypothèses.
Attester + signer : sécuriser la distribution même si PrestaShop ne vérifie pas
Ensuite, il faut signer et attester. Aujourd’hui, l’option la plus simple côté GitHub Actions est d’utiliser les attestations natives (actions/attest-build-provenance) et/ou Sigstore/cosign (signature adossée à OIDC, sans PKI interne lourde).
Point clé : PrestaShop ne vérifiera pas votre signature à l’installation. Donc l’objectif n’est pas de « sécuriser le backoffice » magiquement, mais de sécuriser vos flux de distribution (release Git, registry interne, artefact repository, livraison client) et de pouvoir dire : cet artefact correspond à ce pipeline, sur ce commit, à ce moment.
Pour comprendre le fonctionnement des attestations GitHub et leur vérification côté consommateur, la doc officielle est utile : https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds
Exemple minimal (à adapter) : produire un ZIP déterministe et créer une attestation de provenance.
name: release
on:
push:
tags: ['v*']
permissions:
contents: write
id-token: write # OIDC pour attestation/signature
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set SOURCE_DATE_EPOCH
run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
- name: Install deps (locked)
run: |
composer install --no-dev --prefer-dist --no-interaction
npm ci --ignore-scripts
- name: Build assets
run: npm run build
- name: Create deterministic zip
run: |
rm -f module.zip
TZ=UTC zip -X -r module.zip . \
-x "./.git/*" "./node_modules/*" "./tests/*" "./.github/*"
- name: Attest build provenance
uses: actions/attest-build-provenance@v1
with:
subject-path: module.zip
Deux remarques “terrain” :
npm ci --ignore-scriptsest un bon réflexe anti-surprises, mais certains projets front en dépendent (postinstall). Si vous le retirez, compensez par un contrôle renforcé sur les scripts NPM (audit interne dupackage.json, exécution dans container, permissions minimales).- Pour éviter les ZIP qui “marchent en CI” mais pas en prod, testez aussi un install réel du ZIP (section validation). Le ZIP doit être un livrable, pas un simple packaging.
À partir de là, vous avez une preuve exploitable : si un client vous renvoie un ZIP « suspect », vous comparez les hashes, et vous savez si l’artefact correspond à une release CI attestée. Sans ça, vous êtes en mode forensics à l’aveugle.
SBOM module PrestaShop : formats (CycloneDX/SPDX), génération Composer/NPM, et exploitation vulnérabilités/licences
Un SBOM n’est pas un gadget « compliance ». C’est un index technique de toutes les briques embarquées : packages Composer, dépendances NPM, bibliothèques front, éventuellement binaires, etc. L’NTIA décrit le SBOM comme un inventaire des composants logiciels. Dans un contexte PrestaShop où un module peut embarquer une demi-stack JS + un vendor/ conséquent, cet inventaire devient le moyen le plus fiable de répondre à : « Suis-je impacté par CVE-XXXX dans guzzlehttp/guzzle ? ».
Deux formats dominent :
- SPDX : historique, très utilisé côté licences et conformité.
- CycloneDX : très utilisé en AppSec / supply chain et bien supporté par l’écosystème SCA (référence : https://cyclonedx.org/).
Concrètement, pour un module, CycloneDX est souvent plus simple à exploiter pour la détection de vulnérabilités et l’analyse des composants transitifs.
Générer un SBOM exploitable (et stable)
Génération côté PHP : utilisez le plugin Composer CycloneDX (ou syft/trivy si vous générez un SBOM à partir d’un artefact final). Exemple avec cyclonedx/cyclonedx-php-composer :
composer require --dev cyclonedx/cyclonedx-php-composer
composer cyclonedx:make-sbom --output-format=json --output-file=sbom-php.json
Côté JS : même logique avec un outil CycloneDX dédié à NPM (selon votre stack : npm/pnpm/yarn). L’objectif n’est pas d’avoir “un fichier de plus”, mais un inventaire que vous pouvez stocker, comparer, et requêter lors d’une alerte sécurité.
Important : ne générez pas le SBOM sur un workspace « sale ». Faites-le après un npm ci et un composer install verrouillés. Sans lockfile respecté, votre SBOM varie d’un run à l’autre et ne vaut plus rien.
Checklist rapide “SBOM utile” (spécial modules PrestaShop) :
- [ ] un SBOM par langage (PHP + JS) ou un SBOM fusionné, mais sans mélanger des contextes flous
- [ ] génération en CI (pas sur un poste dev)
- [ ] SBOM attaché à la release (assets) et/ou stocké dans un dépôt d’artefacts
- [ ] même politique de rétention que les ZIP (sinon, impossible d’auditer un incident ancien)
- [ ] idéalement : SBOM signé comme le ZIP (même chaîne de confiance)
Exploiter vulnérabilités et licences : transformer le SBOM en gate
Le SBOM n’est utile que si vous le reliez à une politique automatique. Exemple de garde-fou CI :
- refuser une release si une vulnérabilité Critical/High est détectée dans le graphe de dépendances,
- ou, a minima, exiger une justification (issue/exception) et tracer la décision.
Vous pouvez scanner directement les manifests (composer.lock, package-lock.json) avec composer audit et npm audit. C’est souvent un bon “premier niveau” (rapide, simple), mais attention : la qualité des résultats et la stratégie (fail/build) doivent être alignées avec votre tolérance au risque.
En pratique, pour un module « moyen » (ex. 40–80 packages Composer + 200–600 deps NPM transitives), le SBOM fait gagner un temps massif lors d’une annonce CVE : on passe d’une recherche manuelle (minutes/heures) à une requête automatisée (secondes) sur l’inventaire. Et surtout, vous pouvez répondre précisément : version installée, composant exact, chemin de dépendance.
Astuce très concrète : conservez aussi, en artefact CI, les fichiers composer.lock et package-lock.json utilisés pour construire la release (en plus du SBOM). Le SBOM est l’inventaire “inter-opérable”, les lockfiles sont souvent le “niveau de détail” le plus simple pour reproduire et patcher vite.
Validation automatique des modules : installer/désinstaller en environnement jetable, matrice PS/PHP, et QA de code
Une validation « module » doit refléter la réalité : un ZIP est installé sur une boutique, active des hooks, exécute des migrations et éventuellement des assets. Tester uniquement du PHP isolé ne suffit pas.
L’objectif CI est donc de provisionner une boutique jetable, d’y installer le module, d’exécuter des scénarios de base (activation, configuration minimale, désinstallation), et de vérifier qu’il ne laisse pas de déchets (tables orphelines, overrides persistants, cron non nettoyés). Sur ces aspects, le cœur PrestaShop est perfectible, et beaucoup de problèmes apparaissent uniquement au cycle install/uninstall — sujet connexe traité dans : https://www.expertise-prestashop.fr/2026/06/30/modules-prestashop-desinstallation-propre-performances-et-securite-en-production/.
Matrice PS/PHP : tester ce que vos clients utilisent vraiment
Pour réduire les faux positifs, faites une matrice de test qui colle à vos clients : au minimum PrestaShop 8.1.x et 9.1.x, et deux versions PHP réalistes (ex. 8.2 et 8.3). La compatibilité PrestaShop 9 demande souvent des ajustements (Symfony 6.4, services, routing, etc.) : cf. https://www.expertise-prestashop.fr/2026/07/03/compatibilite-modules-prestashop-9-checklist-avant-migration-securisee/ et, côté architecture, https://www.expertise-prestashop.fr/2026/06/29/module-prestashop-9-structure-services-et-bonnes-pratiques-symfony/.
Un format simple (à adapter) pour cadrer les exécutions CI :
| Axe | Recommandation “module” | Pourquoi |
|---|---|---|
| PrestaShop | 8.1.x + 9.1.x | couvre l’essentiel des écarts (legacy vs Symfony plus strict) |
| PHP | 8.2 + 8.3 | limite les surprises de type dépréciations / types / libs |
| DB | MySQL ou MariaDB (au moins 1) | certains clients sont sur MariaDB, différences réelles sur le SQL |
| Mode | dev et prod (si possible) |
container Symfony et cache se comportent différemment |
Provisionner une boutique jetable : Docker Compose/DDEV et scénarios “smoke”
Le provisioning peut se faire via Docker Compose/DDEV (utile pour reproduire localement exactement ce que la CI exécute). Si vous utilisez DDEV, l’article interne vous donne le socle : https://www.expertise-prestashop.fr/2026/07/01/ddev-outils-developpeur-integres-ddev-exec-ssh-et-extensions-dimage/.
Ensuite, la CI exécute une séquence reproductible :
- installation de PrestaShop (ou restauration d’un dump minimal),
- copie/installation du module (
modules/<nom>/ou via ZIP), - activation,
- smoke tests HTTP (FO/BO) et vérifications “sans erreur”,
- désactivation/désinstallation,
- contrôle de propreté (DB, fichiers, overrides…).
Tests “bêtes mais révélateurs” (souvent plus rentables que 50 assertions unitaires) :
- activer le module, charger une page FO (ex. homepage) et une page BO critique (ex. Modules > Gestionnaire),
- déclencher un hook clé du module (ex.
displayHeader,actionFrontControllerSetMedia, ou un endpoint), - désinstaller, puis recharger la BO (détecte les services cassés, overrides oubliés, fichiers résiduels).
Sur la partie CLI, ne « devinez » pas les commandes : listez-les réellement selon la version via php bin/console list (référence interne : https://www.expertise-prestashop.fr/2026/07/07/commandes-cli-prestashop-liste-categories-et-options-daide/). Selon votre stack, vous pourrez automatiser : cache clear, compilation du container Symfony, warmup, exécution de commandes métier, etc.
QA code : réduire les régressions silencieuses propres aux modules
En parallèle, la validation « code » doit être industrialisée. À ce niveau, PHPStan/Rector est un minimum (référence interne : https://www.expertise-prestashop.fr/2026/05/18/phpstan-et-rector-industrialiser-la-qualite-du-code-php/). Ajoutez aussi :
- contrôle de style (
php-cs-fixer/ PHP_CodeSniffer), - tests unitaires (PHPUnit) et, si possible, tests d’intégration sur une DB éphémère,
- détection de secrets (GitHub secret scanning ou
gitleaks), composer validate+composer audit.
L’enjeu n’est pas « être puriste », mais d’éviter les régressions silencieuses typiques des modules :
- changement de signature de hook,
- service Symfony manquant (et BO cassée),
- compat PHP cassée par une dépendance,
- SQL non compatible MySQL/MariaDB version client,
- endpoint AJAX exposé sans contrôle (token/permissions),
- fichiers laissés sur disque après désinstallation (surface d’attaque inutile).
Garde-fous de release : policy-as-code, seuils de sécurité, et traçabilité exploitable en production
Le trio provenance/SBOM/validation n’a de valeur que si vous imposez des gates strictes à la release. Sinon, vous produisez des rapports que personne ne lit.
La manière saine de faire est de formaliser une policy-as-code, par exemple :
- aucune release sans attestation de provenance,
- aucun tag sans SBOM attaché,
- aucune vulnérabilité High/Critical sans décision tracée (acceptation de risque avec ticket + échéance),
- aucune licence non autorisée (liste allow/deny).
Sur GitHub, ça passe par des branches protégées, des checks requis, et des permissions minimales. Sur GitLab : règles de merge + pipelines protégés.
Pour rendre la policy concrète (et éviter “ça dépend”), définissez des seuils simples. Exemple de grille de décision :
| Contrôle | Bloquant ? | Exception possible ? | Trace attendue |
|---|---|---|---|
| Provenance/attestation | Oui | Rarement | lien vers run CI + commit/tag |
| SBOM présent | Oui | Non | assets de release |
| Vulnérabilités Critical | Oui | Exception cadrée | issue + justification + date de correction |
| Vulnérabilités High | Souvent | Oui | idem |
| Licences interdites | Oui | Exception très rare | validation juridique/contrat client |
| Tests install/uninstall | Oui (sur tag) | Non | logs CI + artefacts |
Sur la sécurité pure PrestaShop, gardez en tête qu’un module peut devenir un point d’entrée (upload, endpoints AJAX, webhooks, etc.). Les contrôles CI ne remplacent pas le durcissement infra, mais ils réduisent drastiquement l’introduction d’une vulnérabilité connue. Pour le cadrage global (WAF, journalisation, durcissement, patch management), vous avez des références internes complémentaires :
- durcissement et mises à jour : https://www.expertise-prestashop.fr/2026/07/06/securite-prestashop-mises-a-jour-ssl-et-durcissement-htaccess/
- sécurité « pro » 2026 : https://www.expertise-prestashop.fr/2026/04/20/securite-prestashop-2026-risques-majeurs-et-protections-professionnelles/
- automatisation et moindre privilège : https://www.expertise-prestashop.fr/2026/07/01/automatisation-prestashop-securite-rgpd-moindre-privilege-et-journaux-daudit/
La performance CI compte aussi, sinon les devs vont contourner le pipeline. Appliquez du cache intelligemment : cache Composer, cache NPM, layers Docker/BuildKit (voir l’article BuildKit déjà cité), et n’exécutez les tests e2e complets que sur tags/PR critiques. Côté runtime, ne confondez pas optimisation CI et optimisation production, mais gardez une cohérence d’environnement (versions PHP, extensions). À ce sujet, vérifier et aligner OPcache peut éviter des écarts env/CI en staging : https://www.expertise-prestashop.fr/2026/07/09/opcache-php-activer-et-verifier-lextension-dans-cpanel/.
Enfin, traçabilité en production : stockez vos ZIP + SBOM + attestations dans un artefact repository (ou au minimum en assets de release), et référencez-les dans vos runbooks. Quand un incident arrive, vous devez pouvoir répondre en 5 minutes :
- quelle version exacte du module est en prod,
- avec quelles dépendances,
- quel pipeline l’a construite,
- et si l’artefact correspond bien à une release officielle.
La maintenance opérationnelle (sauvegardes chiffrées, sécurité serveur, restauration) reste le dernier filet de sécurité : https://www.expertise-prestashop.fr/2026/07/10/maintenance-prestashop-managed-services-securite-serveur-sauvegardes-chiffrees/.
Si vous appliquez ces garde-fous, vous n’empêchez pas tous les bugs (PrestaShop reste un écosystème hétérogène, et les boutiques clientes ont des combinaisons modules/thèmes parfois non testables exhaustivement). En revanche, vous réduisez fortement les classes d’incidents les plus coûteuses : compromission supply chain, régression non détectée à l’installation, et incapacité à prouver ce qui a été livré.
