Table des matières :
- Webservice PrestaShop : modèle d’authentification et surface d’attaque
- Sécuriser les clés API : génération, stockage et rotation (malgré l’absence d’expiration native)
- Permissions Webservice : appliquer le moindre privilège et éviter les droits « trop larges »
- Durcissement réseau : HTTPS strict, filtrage IP, rate limiting et proxy
- Journalisation, détection d’abus et procédure de révocation (playbook réaliste)
Webservice PrestaShop : modèle d’authentification et surface d’attaque
Sur PrestaShop 8.2.x et 9.2.x (tests réalisés en PHP 8.3, Nginx 1.26 et Apache 2.4), le Webservice historique expose l’endpoint /api/ et une authentification basée sur une clé API (webservice key). Concrètement, c’est du HTTP Basic Auth : la clé est utilisée comme username et le mot de passe est vide. Cette simplicité a un avantage (intégrations rapides), mais elle impose une discipline stricte côté sécurité parce que la clé donne accès à des ressources CRUD potentiellement critiques (clients, commandes, adresses, stocks). Pour un rappel des patterns CRUD et des ressources, la base est déjà couverte ici : API Webservice PrestaShop : guide CRUD et ressources développeur.
Deux rappels utiles (car ils reviennent en incident) :
- Basic Auth n’est pas du chiffrement : la valeur
Authorization: Basic ...est juste encodée en Base64. Sans TLS, elle est lisible en clair par un intermédiaire réseau. - Le “compte” est la clé : contrairement à un couple login/mot de passe, vous ne pouvez pas imposer de complexité, de MFA, ni de politiques dynamiques par utilisateur. Une clé qui fuite = accès immédiat.
Le point faible n’est pas le mécanisme en lui-même, mais le fait qu’il est souvent déployé « tel quel », sans périmètre réseau ni hygiène de secret. Le RFC sur Basic Auth le dit sans détour : « The Basic authentication scheme is not considered to be a secure method of user authentication unless used in conjunction with some external secure system such as TLS » (RFC 7617, The ‘Basic’ HTTP Authentication Scheme : https://www.rfc-editor.org/rfc/rfc7617). Traduction opérationnelle : si votre Webservice PrestaShop répond en HTTP (même temporairement), la clé est compromise.
Deuxième erreur classique : transmettre la clé dans l’URL (ex. ?ws_key=...). Même si PrestaShop l’accepte selon les intégrations, c’est une bombe à retardement : logs d’accès, outils APM, reverse proxies, referers, partages d’URL, historique navigateur (dans certains cas), etc. Le RFC 6750 (Bearer Token) vise un autre type de jeton mais pose un principe utilisable tel quel en sécurité API : « Clients MUST NOT use the URI query parameter method to send bearer tokens. » (RFC 6750 : https://www.rfc-editor.org/rfc/rfc6750). La bonne pratique reste : clé uniquement dans l’en-tête Authorization, et uniquement sur TLS.
Exemple minimal côté client (en-tête Basic, sans fuite dans l’URL) :
curl -sS \
-H 'Authorization: Basic '"$(printf '%s:' "$PS_WS_KEY" | base64)" \
'https://shop.example.com/api/orders?display=full&limit=5'
À garder en tête côté surface d’attaque (modèle de menace très concret) :
- Exfiltration de données : une clé ayant
GETsurcustomers/addresses/orderspeut suffire à sortir des données personnelles. En France/UE, c’est typiquement un scénario RGPD (article 32 : sécurité du traitement + notion d’accès strictement nécessaire). - Altération “silencieuse” : une clé avec
PUTsurproducts/stock_availables/specific_pricespeut dégrader un catalogue sans déclencher d’alertes immédiates (prix écrasés, stocks à zéro, images supprimées…). - Déni de service applicatif : sans rate limiting, une boucle de synchronisation ou une clé compromise peut saturer PHP-FPM et la base (pics de
500/503), même sans “attaque” sophistiquée.
Le modèle de menace à garder en tête est trivial : une clé = un compte = un périmètre de ressources. PrestaShop ne fournit pas nativement d’OAuth, pas de scopes dynamiques, pas de TTL de clé, et pas de limitation de débit côté core. Donc la sécurité doit être reconstruite autour : permissions minimales, segmentation des clés, filtrage réseau, journalisation et rotation.
Enfin, un point “terrain” : certaines chaînes techniques (CDN, proxy d’entreprise, passerelles API) peuvent supprimer ou réécrire l’en-tête Authorization si mal configurées. Résultat : l’intégration “ne marche pas”, et l’on retombe dans le mauvais réflexe ?ws_key=.... L’objectif est l’inverse : corriger la chaîne HTTP pour que l’en-tête soit transmis correctement, et bloquer explicitement la variante query-string (voir plus bas, section durcissement réseau).
Sécuriser les clés API : génération, stockage et rotation (malgré l’absence d’expiration native)
Dans le back-office (Paramètres avancés → Webservice), PrestaShop génère généralement une clé alphanumérique longue (souvent 32 caractères). Ça suffit si vous traitez cette valeur comme un secret. Le problème récurrent n’est pas l’entropie, mais le cycle de vie : une clé créée pour un prestataire reste active des années, se retrouve copiée dans des tickets support, des exports, des fichiers .env committés par erreur, ou des dashboards internes accessibles trop largement.
Approche qui tient en prod : 1 clé par intégration (ERP, PIM, OMS, WMS, BI…), 1 clé par environnement (prod, staging, dev) et zéro réutilisation. En cas de fuite, vous limitez le blast radius et vous pouvez révoquer une seule clé sans casser toutes les synchronisations. Si vous construisez un connecteur Odoo/ERP, le sujet est adjacent (webservice + sécurité + signatures) : Connecteur PrestaShop Odoo : configuration Webservice, webhooks signés et sécurité.
Pour que ça reste opérationnel dans une organisation (agence, DSI, infogérance), la “discipline de secret” peut se formaliser en checklist très simple :
- La clé n’apparaît jamais dans : URL, captures d’écran, exports CSV, tickets (ou alors redaction systématique).
- La clé n’est jamais stockée dans : collections Postman partagées, documentation interne non restreinte, dépôt Git (même privé).
- L’accès à la clé est limité aux personnes/process qui en ont besoin (principe du moindre privilège… appliqué aux secrets eux-mêmes).
- La description de la clé (champ description côté PrestaShop) inclut propriétaire + usage + date (ex.
ERP Sage - stock - prod - owner: ops - created: 2026-10-01), pour éviter les “clés orphelines”.
Pour le stockage : évitez les fichiers en clair sur le serveur applicatif, et évitez d’exposer la clé à des logs (reverse proxy, applicatif, CI). En pratique, privilégiez un secret manager (Vault, AWS Secrets Manager, Azure Key Vault, Doppler, 1Password Secrets Automation…) ou, a minima, des variables d’environnement injectées par votre orchestrateur (systemd, Docker/Kubernetes, pipeline CI/CD). Côté Nginx/Apache, vérifiez que votre format de logs ne journalise pas $http_authorization (Nginx) et que vos modules WAF/trace ne dumpent pas les headers.
PrestaShop n’implémente pas nativement : expiration de clés, rotation automatique, ni historique d’usage par clé. Vous devez donc industrialiser la rotation. Cadre simple (à adapter à votre risque) : rotation trimestrielle pour les intégrations sensibles (commandes/clients), semestrielle sinon, et rotation immédiate après départ d’un prestataire ou suspicion de fuite.
Procédure robuste (qui évite une coupure) :
- Créer une nouvelle clé en la documentant (qui, quoi, où) et en lui appliquant les mêmes permissions (ou mieux : permissions revues à la baisse).
- Déployer la nouvelle clé côté intégration (ERP/PIM) et vérifier sur staging (auth, volumétrie, comportements “retry”).
- Activer la nouvelle clé en prod, basculer le trafic (souvent un simple changement de secret côté connecteur).
- Surveiller 24–48 h (erreurs 401/403, 429, 500, volume).
- Désactiver l’ancienne clé, puis la supprimer.
Pour auditer l’existant en base (préfixe ps_ à adapter), utile pour inventorier les comptes Webservice et leurs permissions :
SELECT id_webservice_account, key, description, active
FROM ps_webservice_account
ORDER BY id_webservice_account DESC;
SELECT p.id_webservice_account, p.resource, p.method
FROM ps_webservice_permission p
ORDER BY p.id_webservice_account, p.resource, p.method;
Note : si vous avez un dump SQL qui circule (support, prestataire, staging), les clés Webservice partent avec. C’est un angle mort fréquent dans les migrations et clonages (à cadrer en amont comme vous le feriez pour les secrets SMTP/paiement). Sur le volet production/staging, la méthodologie de bascule et de durcissement est connexe à une migration : Méthodologie de migration PrestaShop 1.7 vers 9 en production.
Un “petit” plus qui change tout en exploitation : désactiver le Webservice si vous ne l’utilisez pas (même temporairement). Réduire la surface d’attaque reste le contrôle le plus efficace : pas d’endpoint exposé, pas de brute force de clé, pas de scans sur /api/.
Permissions Webservice : appliquer le moindre privilège et éviter les droits « trop larges »
Le cœur du sujet « sécuriser les clés API et permissions » est là : une clé ne doit jamais être “full access”. Dans PrestaShop, la matrice des permissions Webservice se fait par ressource (ex. orders, customers, products, stock_availables, etc.) et par méthode (GET, POST, PUT, DELETE, parfois HEAD). L’erreur typique est de cocher large « pour que ça marche », surtout sur orders, customers, addresses et order_histories.
Le principe à appliquer est celui du moindre privilège (least privilege) : donner uniquement les couples (ressource × méthode) nécessaires. Exemple concret : une synchronisation de stock depuis un WMS n’a besoin que de GET sur products (pour faire la correspondance) et PUT sur stock_availables (pour pousser la quantité) — pas de POST/DELETE sur products, et certainement pas d’accès aux clients/commandes. À l’inverse, un export BI peut être strictement GET (read-only) sur orders, order_details, customers selon la légalité et vos règles internes.
Une façon simple d’éviter les permissions “au doigt mouillé” est de raisonner par cas d’usage. Exemple (indicatif, à ajuster selon votre connecteur et vos besoins) :
| Intégration | Objectif | Ressources PrestaShop typiques | Méthodes minimales | À refuser par défaut |
|---|---|---|---|---|
| ERP (commandes) | Récupérer commandes, mettre à jour statut | orders, order_histories, order_details |
GET + éventuellement POST sur order_histories |
DELETE partout ; accès aux customers si non nécessaire |
| PIM (catalogue) | Pousser fiches produit | products, combinations, images, specific_prices |
GET/POST/PUT selon flux |
DELETE (sauf process maîtrisé) |
| WMS (stock) | Mettre à jour stock | products, stock_availables |
GET + PUT |
POST/DELETE sur products |
| BI / ETL | Analyser ventes | orders, order_details (+ customers si base légale) |
GET uniquement |
Toute écriture (POST/PUT/DELETE) |
Mini-scenario “réaliste” : un marchand B2C en France connecte un prestataire BI pour analyser les ventes. Le prestataire demande “accès API”. Si vous lui donnez GET sur customers + addresses, vous ouvrez potentiellement la porte à une extraction large de données personnelles, sans nécessité opérationnelle. Souvent, les analyses de vente se font sans adresses : des identifiants client pseudonymisés (ou uniquement des agrégats commandes) suffisent. Le moindre privilège est aussi une réponse pragmatique aux exigences de minimisation des données.
Limite structurelle du Webservice PrestaShop : il n’y a pas de contrôle fin “objet par objet” (pas de BOLA/ABAC natif). Si vous autorisez GET sur orders, la clé peut lire toutes les commandes accessibles via l’API (avec filtres). Même logique pour customers. Si vous devez exposer des données à un tiers sans lui donner une visibilité globale, le bon pattern n’est pas d’empiler des permissions, mais de mettre un proxy applicatif : une API interne (JWT/mTLS/OAuth) qui appelle le Webservice PrestaShop avec une clé “supervisée”, applique vos règles (filtrage par boutique, par date, par périmètre client), et ne renvoie qu’un sous-ensemble. Pour cadrer le risque API, un bon référentiel (lecture) est l’OWASP API Security Top 10.
Trois points de friction en prod méritent d’être explicités :
- Méthodes destructrices :
DELETEest rarement justifié en e-commerce. Même un PIM/ERP doit généralement désactiver, pas supprimer (traçabilité, contraintes légales). GardezDELETEà zéro sauf cas documenté. - Ressources “techniques” : certaines intégrations réclament des ressources annexes (ex.
images,specific_prices,combinations). Donnez-les au cas par cas, sinon vous ouvrez la porte à des modifications de catalogue inattendues. - Couverture fonctionnelle : certains besoins sont mieux servis par l’Admin API (sur PrestaShop 9.x) que par le Webservice legacy. Si votre projet vise PrestaShop 9.2+ et exploite des champs avancés, regardez l’évolution côté Admin API : PrestaShop 9.2 : Extra Properties, champs personnalisés natifs via Admin API.
Enfin, documentez vos choix. Une page interne “Contrat d’intégration” listant : clé utilisée, permissions accordées, IP sources autorisées, volumétrie attendue (req/min), et contact responsable, évite 90% des dérives lors d’un changement de prestataire ou d’une reprise.
Durcissement réseau : HTTPS strict, filtrage IP, rate limiting et proxy
Le Webservice PrestaShop doit être vu comme un endpoint sensible. Le prérequis non négociable : HTTPS partout, avec redirection HTTP→HTTPS et idéalement HSTS. Si vous êtes sur une infra type Lightsail/VM, le minimum est un certificat Let’s Encrypt et un renouvellement automatisé ; pour une mise en place propre (DNS + HTTPS), voir : DNS + nom de domaine + HTTPS Let’s Encrypt sur PrestaShop Lightsail. Dans un contexte plus général d’auto-hébergement, les fondamentaux (patching, durcissement, maintenance) restent valables : PrestaShop auto-hébergé : prérequis d’installation, maintenance et sécurité.
Deux précisions souvent oubliées sur “HTTPS strict” :
- Assurez-vous que
/api/n’est pas accessible via un hostname “secondaire” (ancien domaine, sous-domaine technique) avec un TLS moins strict. - En cas de reverse proxy/CDN, vérifiez le chiffrement jusqu’à l’origine (TLS entre proxy et serveur), pas uniquement “visiteur → CDN”.
Deuxième couche : filtrage IP sur /api/. PrestaShop ne propose pas d’allowlist IP par clé au niveau applicatif, donc faites-le au niveau reverse proxy. Exemple Nginx :
location ^~ /api/ {
allow 203.0.113.10; # ERP
allow 203.0.113.11; # ETL
deny all;
# Optionnel : ne pas logguer si vous suspectez des fuites
# access_log /var/log/nginx/api_access.log main;
proxy_pass http://php_upstream;
}
Sur Apache, même logique via Require ip. Si vous ne pouvez pas filtrer par IP (IP dynamiques, SaaS), basculez vers un VPN site-to-site, ou utilisez un proxy API (Kong, Traefik, Nginx) qui impose une authentification moderne (mTLS, JWT signé) et ne relaie vers PrestaShop qu’après contrôle.
Mesure très efficace (et facile) pour casser la mauvaise habitude ?ws_key= : refuser la clé en query string au niveau proxy. Exemple Nginx :
location ^~ /api/ {
if ($arg_ws_key != "") { return 403; }
# ...
}
Troisième couche : rate limiting. Sans limites, une clé compromise peut provoquer un DDoS applicatif (DB saturée, locks, 503). Vous pouvez faire du rate limit au niveau Nginx (limit_req) ou via un WAF/CDN. Exemple Nginx (à calibrer) :
limit_req_zone $binary_remote_addr zone=api_per_ip:10m rate=5r/s;
location ^~ /api/ {
limit_req zone=api_per_ip burst=20 nodelay;
# ...
}
Sur la stratégie de quotas et la sémantique des erreurs 429 (important pour que l’intégration réessaie correctement), voir : Comprendre les API rate limits (quotas, headers et erreurs 429). Point d’attention : si vous mettez Cloudflare/Fastly devant, assurez-vous que /api/ n’est pas “mis en cache” et que les règles WAF ne bloquent pas vos payloads XML/JSON légitimes.
Dernier levier (souvent décisif) : terminer l’exposition publique de /api/. Si seules des intégrations internes en ont besoin, vous pouvez :
- restreindre
/api/à un réseau privé (VPN), - ou publier un proxy API public qui fait mTLS/JWT, et ne contacte PrestaShop qu’en réseau privé.
Cela transforme un Basic Auth “statique” en un schéma moderne sans modifier le core PrestaShop.
Journalisation, détection d’abus et procédure de révocation (playbook réaliste)
Sécuriser les clés API, ce n’est pas juste réduire les permissions : c’est aussi détecter vite une anomalie et savoir révoquer sans casser la prod. Le problème côté PrestaShop core : la journalisation Webservice n’est pas conçue comme un SIEM. Vous aurez rarement un log applicatif “par clé” exploitable sans instrumentation. La voie pragmatique : logs reverse proxy (Nginx/Apache) + corrélation IP + endpoints + taux d’erreur, en s’assurant de ne jamais logguer la clé (donc pas de query string, et attention aux headers en debug).
Point de vigilance côté Nginx : si votre log_format utilise $remote_user, et que Basic Auth est en place, $remote_user peut correspondre au “username”… donc à la clé. Si vous avez un doute, retirez $remote_user des logs pour la location /api/, ou utilisez un format dédié.
Exemple d’approche pragmatique : un fichier de log séparé pour l’API, avec uniquement les champs nécessaires à l’investigation (IP, URI, statut, temps), sans secrets :
log_format api_safe '$remote_addr - $time_local '
'"$request" $status $body_bytes_sent '
'rt=$request_time uat="$http_user_agent"';
location ^~ /api/ {
access_log /var/log/nginx/api_access.log api_safe;
# ...
}
En pratique, vous cherchez des signaux simples :
- Explosion des
401/403sur/api/(scan de clés, brute force, intégration cassée). - Pic de
500/503corrélé à/api/(requêtes coûteuses, boucle de retry, attaque). - Augmentation du volume
GETsur ressources sensibles (customers,addresses,orders) à des horaires incohérents. - Apparition de patterns “scraping” :
display=full+ pagination agressive, ou filtres larges sur des ressources à données personnelles.
Pour la supervision et l’impact prod (erreurs 503, saturation PHP-FPM, DB), vous pouvez réutiliser les méthodologies de monitoring orientées e-commerce : Monitoring PrestaShop : KPI e-commerce, paiements et prévention des erreurs 503 et, côté perf serveur, les patterns PHP-FPM/OPcache/Redis : Accélérer un back-office PrestaShop lent avec OPcache, PHP-FPM et Redis.
Pour rendre la détection actionnable, définissez 2–3 alertes “basiques” (sans usine à gaz) :
- Erreur auth :
401/403> X/min pendant Y minutes sur/api/. - Saturation : hausse simultanée
5xx+request_timesur/api/. - Volume anormal : requêtes
/api/> baseline habituel (par IP ou global).
Playbook de révocation (à tester avant l’incident) :
- Confinement : si possible, bloquer
/api/sur le reverse proxy sauf IP connues, ou activer une règle WAF temporaire. - Rotation immédiate : créer une nouvelle clé, basculer l’intégration, désactiver l’ancienne. Si plusieurs intégrations partagent une clé (mauvaise pratique), vous aurez un incident plus coûteux — d’où l’intérêt de segmenter.
- Analyse : exploiter les logs proxy (IP, UA, ressources ciblées) et vérifier les effets de bord (modifications catalogue, commandes, données personnelles).
- Remédiation : réduire les permissions si elles étaient trop larges, et verrouiller le réseau (allowlist, VPN, proxy) pour éviter une récidive.
Dernier point souvent oublié : la sécurité Webservice se dégrade aussi via l’écosystème (modules vulnérables, injections, skimmers). Une compromission front peut exfiltrer des secrets de config ou des dumps, puis remonter vers l’API. Gardez une routine de patching et de scanning, et si vous suspectez une compromission e-commerce type skimmer, traitez-la comme un incident complet : Skimmer Magecart PrestaShop : détecter et nettoyer une infection.
Si vous deviez réduire cet article à une règle unique : une clé Webservice PrestaShop n’est acceptable en prod que si elle est (1) transmise uniquement via Authorization sur TLS, (2) limitée en permissions au strict nécessaire, (3) confinée réseau, (4) rotatable rapidement, (5) observable via logs et alerting.




