Whether you run Community or Enterprise, self-hosted or on a partner server, the same principles apply. Details change with version and hosting, but exposure, identity, rights, backups and ownership stay the baseline (see Odoo Community vs Enterprise for edition context).
The threat model in plain words
Most compromised Odoo instances suffer from one of these:
- The web database manager reachable without network restriction, sometimes with a weak master password
- Stolen or guessed user passwords, especially shared administrator accounts without 2FA
- Over-broad access rights: everyone in "Settings / Administration" or custom groups that grant too much
- Unmaintained third-party modules with known issues, or custom code deployed without review
- PostgreSQL or SSH exposed to the internet, or staging copies of production left online
- Backups that restore the database but not attachments in the filestore, or dumps stored where anyone can download them
- A former integrator's access that was never removed (see the offboarding access checklist)
Attackers often want resaleable data, fraudulent purchase orders, changed bank details on vendor records, or a foothold to send invoice fraud from a trusted domain (see phishing and invoice fraud in SMEs).
Step 1: Close public database tools
Odoo's database manager is convenient during setup. On production it is a magnet for automated scans.
- Set
list_db = Falseinodoo.confso anonymous visitors cannot list databases - Use
dbfilterso each hostname maps to one database and stray names are rejected - Choose a strong master password for database operations, store it in your password manager, and never leave the default empty on a reachable server
- Block
/web/database/managerand/web/database/selectorat the reverse proxy unless you truly need them from outside, and then restrict by IP or VPN - Keep demo databases and old test installs off public URLs
- Know where the instance runs and who can reach it (see where your data lives and hardening a new server in the first hour)
Hiding the manager is not optional hygiene. It is the difference between "login page only" and "create or drop databases from the browser."
Step 2: Control the module inventory
Every installed app is code that runs with your business data.
- List installed modules with owner, purpose, and source: official, OCA, commercial, or custom
- Uninstall what you do not use. Disabled modules may still leave models, cron jobs or menu entries behind until cleaned up properly
- Prefer maintained modules with a clear licence and upgrade path. Community vs Enterprise boundaries affect what you can patch yourself (see Community vs Enterprise)
- Review custom modules before production: SQL, external calls, sudo usage, and scheduled actions
- Ask integrators for runbooks and module lists at delivery (see documentation to require at handover)
- For shops and stock-heavy setups, align security work with process risk (see Odoo shop and stock pitfalls)
Step 3: Update Odoo and dependencies safely
- Track your exact Odoo version and apply security patches on a defined schedule
- Keep Python, PostgreSQL and the OS on supported versions. End-of-life components are a common entry point
- Test upgrades on a staging copy that does not hold live personal data where you can avoid it (see GDPR and test environments)
- Back up before every upgrade attempt
- Plan custom module compatibility before major version jumps, not the night before go-live
- Subscribe to Odoo security advisories and to notices for critical third-party modules you rely on
If a module is abandoned and blocks patching, replace it. Waiting is not a strategy.
Step 4: Users, authentication and 2FA
- No shared "admin@company" login for daily work. Named accounts for every person
- Unique, long passwords from a password manager (see password management and 2FA for a small team)
- Two-factor authentication for administrators, accounting, and anyone who can change bank details or user rights. Use the edition-appropriate mechanism and enforce it in policy even when Odoo cannot force every portal user
- Separate integrator accounts from employee accounts, with expiry and review dates
- Portal and public users: minimal rights, inactive partners disabled, signup closed unless you need it
- Review the user list every few months. Unknown administrators or API keys are worth investigating
- After someone leaves, run the offboarding access checklist, including Odoo, email, VPN, hosting panel and repository access
Not sure how exposed your Odoo is?
We can review exposure, modules, backups and access rights, and suggest a baseline that fits your edition and hosting.
Step 5: Access rights and least privilege
Odoo security is groups, record rules, and model access rights. "Everyone is admin" defeats the point of an ERP.
- Map roles to groups: sales sees sales, warehouse sees stock, accounting sees journals you intend
- Avoid handing out "Settings / Administration" for convenience. Use delegated groups and document who can install apps
- Review record rules on custom modules. A missing rule can leak rows across companies or departments
- Limit users with sudo or technical settings. Developers get their own login, not yours
- Apply least privilege at team scale (see least privilege for a ten-person team)
- Export rights matter: restrict spreadsheet exports where payroll or health data is involved
Step 6: Harden the server and network path
- HTTPS everywhere, with automatic certificate renewal and monitoring (see DNS, SSL and silent outages)
- PostgreSQL listens on localhost or a private network only, never on a public IP without strict firewall rules
- SSH key-based login, no password root, firewall default deny, fail2ban or equivalent where it helps
- Run Odoo behind a reverse proxy with sensible timeouts and request size limits
- Disable debug mode and developer assets on production
- Protect
odoo.conf, backup dumps, and.gitfrom web access. Directory listing off - When you change DNS or hosting, plan mail and records carefully (see migrating DNS without breaking email)
Step 7: Backups that include the filestore
Odoo attachments, PDFs and some reports live in the filestore. A database-only dump is an incomplete restore (see backups that actually restore).
- Backup PostgreSQL and the filestore directory together, with consistent timing or brief maintenance windows when needed
- Store copies off the application server, under credentials your hosting vendor does not share with production
- Keep several generations. Fraud or ransomware may stay unnoticed for days
- Encrypt backups that hold personal data, and control who can download them
- Run a restore test at least twice a year: new database, filestore in place, login, open an attachment
- Document restore steps in the handover pack you expect from integrators (see documentation at delivery)
Step 8: Monitor, log and own the stack
- Uptime checks on
/web/loginfrom outside - Alerts on disk usage, failed logins, and sudden growth in outbound mail
- Review Odoo logs and reverse-proxy logs for repeated probes on database URLs and XML-RPC if enabled
- Track cron failures: silent scheduled jobs can break stock or accounting without a user noticing
- Hosting panel, domain registrar, DNS and backup account in your name, with 2FA (see the 30-minute account ownership audit)
- Contracts that say who holds keys, data location and exit terms (see clauses for tech contractors and GDPR register and DPA for agencies)
Attacker quick test (15 minutes)
Run this from outside your office network, like a stranger on the internet would.
- Open
https://your-odoo-domain/web/database/manager. You should not get a working database administration screen - Try listing databases at
/web/database/selector. Withlist_db = False, expect a refusal or login-only flow - Attempt obvious passwords on a dormant test account you control, not on real users. If policy allows trivial passwords, fix policy before attackers try the same
- From a port scanner you trust, confirm PostgreSQL and Redis are not open to the world
- Search for staging hostnames or old project URLs still pointing at a copy of production
- Look for backup files,
.sqldumps or.ziparchives under the web root or a guessable path - Sign in as a low-privilege user you created for the test. Confirm you cannot open accounting, user management or vendor bank details you should not see
Any "yes, that worked" is a ticket, not a debate.
Common mistakes
- Production reachable with
list_db = Trueand an empty master password - One administrator password shared in a chat channel
- Integrator left with permanent superuser access after go-live
- Dozens of installed apps, half unused, never updated
- Nightly database dump but no filestore backup
- Staging clone of production on a public URL without IP restriction
- PostgreSQL exposed "temporarily" and forgotten
- Record rules assumed to be fine because "we only use standard apps"
- No restore test since the initial deployment
- Domain and hosting paid by the agency, in the agency's account
Checklist
list_db = False, strong master password,dbfilterset- Database manager blocked or IP-restricted at the proxy
- Module inventory documented, unused apps removed or planned for removal
- Supported Odoo, OS, Python and PostgreSQL versions, patch routine defined
- Named users, password manager, 2FA on privileged accounts
- Groups and record rules reviewed, no casual Settings administrators
- HTTPS with monitored certificates, PostgreSQL not public
- Database and filestore backed up off-server, restore tested
- Monitoring on uptime, disk and authentication failures
- Hosting, DNS and backups owned by the company, integrator access time-boxed
Want help hardening production Odoo?
Describe your edition, hosting, modules and who has access. We will suggest sensible next steps.
Community ou Enterprise, auto-hébergé ou serveur partenaire, les principes restent les mêmes. Les détails varient selon la version et l'hébergement, mais exposition, identité, droits, sauvegardes et propriété forment la base (voir Odoo Community vs Enterprise pour le contexte d'édition).
Le modèle de menace, en clair
La plupart des instances Odoo compromises souffrent d'un de ces problèmes:
- Gestionnaire de bases web joignable sans restriction réseau, parfois avec un mot de passe maître faible
- Mots de passe volés ou devinés, surtout comptes administrateur partagés sans 2FA
- Droits trop larges: tout le monde en « Paramètres / Administration » ou groupes sur mesure trop permissifs
- Modules tiers non maintenus, ou code sur mesure déployé sans relecture
- PostgreSQL ou SSH exposés sur Internet, ou copies de production laissées en staging public
- Sauvegardes qui restaurent la base mais pas les pièces jointes du filestore, ou dumps téléchargeables par n'importe qui
- Accès d'un intégrateur jamais retiré après mise en production (voir la checklist de retrait d'accès)
Les attaquants visent souvent la revente de données, des commandes frauduleuses, des coordonnées bancaires fournisseur modifiées, ou une base pour envoyer de fausses factures depuis un domaine de confiance (voir hameçonnage et fraude aux factures en PME).
Étape 1: Fermer les outils publics sur les bases
Le gestionnaire de bases Odoo est pratique à l'installation. En production, il attire les scans automatiques.
list_db = Falsedansodoo.confpour que les visiteurs anonymes ne listent pas les basesdbfilterpour qu'un nom d'hôte ne serve qu'une base et que les autres noms soient refusés- Mot de passe maître fort pour les opérations sur les bases, stocké dans le gestionnaire de mots de passe, jamais laissé vide sur un serveur joignable
- Bloquer
/web/database/manageret/web/database/selectorau reverse proxy sauf besoin réel depuis l'extérieur, et alors restreindre par IP ou VPN - Retirer les bases démo et anciennes installs de test des URL publiques
- Savoir où tourne l'instance et qui peut l'atteindre (voir où vivent vos données et durcir un serveur neuf dans la première heure)
Masquer le gestionnaire n'est pas un détail. C'est la différence entre « page de connexion seulement » et « créer ou supprimer des bases depuis le navigateur ».
Étape 2: Maîtriser l'inventaire des modules
Chaque application installée est du code qui s'exécute avec vos données métier.
- Lister les modules installés avec responsable, rôle et source: officiel, OCA, commercial ou sur mesure
- Désinstaller ce que vous n'utilisez pas. Un module désactivé peut laisser modèles, crons ou menus jusqu'à nettoyage correct
- Privilégier des modules maintenus, licence claire et chemin de mise à jour. Community et Enterprise changent ce que vous pouvez corriger vous-mêmes (voir Community vs Enterprise)
- Relire le code sur mesure avant production: SQL, appels externes, usage sudo, actions planifiées
- Exiger runbooks et listes de modules à la livraison (voir documentation à exiger à la livraison)
- Pour boutique et stock, aligner sécurité et risque process (voir boutique Odoo et pièges stock)
Étape 3: Mettre à jour Odoo et les dépendances sans casser
- Connaître la version exacte d'Odoo et appliquer les correctifs sécurité selon un calendrier défini
- Garder Python, PostgreSQL et l'OS sur des versions supportées. Les composants en fin de vie sont une entrée fréquente
- Tester les montées de version sur un staging sans données personnelles réelles quand vous le pouvez (voir RGPD et environnements de test)
- Sauvegarder avant chaque tentative de mise à jour
- Anticiper la compatibilité des modules sur mesure avant un saut de version majeur, pas la veille du go-live
- S'abonner aux avis sécurité Odoo et aux alertes des modules tiers critiques
Si un module est abandonné et bloque les correctifs, remplacez-le. Attendre n'est pas une stratégie.
Étape 4: Utilisateurs, authentification et 2FA
- Pas de login « admin@societe » partagé au quotidien. Un compte nominatif par personne
- Mots de passe uniques et longs via un gestionnaire (voir gestion des mots de passe et 2FA pour une petite équipe)
- Double authentification pour administrateurs, comptabilité et toute personne pouvant modifier RIB ou droits utilisateurs. Mécanisme adapté à l'édition, et politique interne même si Odoo ne force pas chaque utilisateur portail
- Comptes intégrateur séparés des comptes salariés, avec date de fin et revue
- Utilisateurs portail et public: droits minimaux, partenaires inactifs désactivés, inscription fermée si inutile
- Relire la liste des utilisateurs tous les quelques mois. Administrateurs ou clés API inconnus méritent une enquête
- Au départ d'une personne, appliquer la checklist de retrait d'accès, Odoo, mail, VPN, hébergement et dépôt de code inclus
Vous ne savez pas à quel point votre Odoo est exposé ?
On peut passer en revue exposition, modules, sauvegardes et droits, et proposer une base adaptée à votre édition et hébergement.
Étape 5: Droits d'accès et moindre privilège
La sécurité Odoo repose sur les groupes, règles d'enregistrement et droits par modèle. « Tout le monde admin » annule l'intérêt d'un ERP.
- Associer les rôles métier aux groupes: ventes voit ventes, entrepôt voit stock, compta voit les journaux prévus
- Ne pas distribuer « Paramètres / Administration » par facilité. Déléguer des groupes et documenter qui peut installer des apps
- Relire les règles sur modules sur mesure. Une règle manquante peut fuiter des lignes entre sociétés ou services
- Limiter les utilisateurs sudo ou réglages techniques. Les développeurs ont leur propre login, pas le vôtre
- Appliquer le moindre privilège à l'échelle de l'équipe (voir moindre privilège pour une équipe de dix personnes)
- Les exports comptent: restreindre les exports tableur quand paie ou données de santé sont en jeu
Étape 6: Durcir serveur et chemin réseau
- HTTPS partout, renouvellement automatique des certificats et surveillance (voir DNS, SSL et pannes silencieuses)
- PostgreSQL en écoute localhost ou réseau privé uniquement, pas sur IP publique sans pare-feu strict
- SSH par clé, pas de root par mot de passe, pare-feu en refus par défaut, fail2ban ou équivalent si utile
- Odoo derrière un reverse proxy avec timeouts et tailles de requête raisonnables
- Mode debug et assets développeur désactivés en production
- Protéger
odoo.conf, dumps de sauvegarde et.gitde l'accès web. Listage de répertoires off - Lors d'un changement DNS ou hébergeur, planifier mail et enregistrements (voir migrer le DNS sans casser l'email)
Étape 7: Sauvegardes avec filestore
Pièces jointes, PDF et certains rapports vivent dans le filestore. Un dump base seul est une restauration incomplète (voir des sauvegardes qui restaurent vraiment).
- Sauvegarder PostgreSQL et le répertoire filestore ensemble, avec timing cohérent ou courte fenêtre de maintenance si besoin
- Copies hors serveur applicatif, identifiants distincts de la production
- Plusieurs générations. Fraude ou ransomware peut rester invisible plusieurs jours
- Chiffrer les sauvegardes avec données personnelles, contrôler qui peut les télécharger
- Test de restauration au moins deux fois par an: nouvelle base, filestore en place, connexion, ouverture d'une pièce jointe
- Documenter la procédure de restauration dans le pack livré par l'intégrateur (voir documentation à la livraison)
Étape 8: Surveiller, journaliser et posséder la stack
- Contrôle de disponibilité sur
/web/logindepuis l'extérieur - Alertes sur disque, échecs de connexion et hausse du courrier sortant
- Revue des logs Odoo et reverse proxy pour sondes répétées sur URLs de bases et XML-RPC si activé
- Suivre les échecs de crons: des jobs silencieux peuvent casser stock ou compta sans alerte utilisateur
- Panneau hébergeur, registrar, DNS et compte sauvegarde à votre nom, avec 2FA (voir l'audit de propriété des comptes en 30 minutes)
- Contrats qui précisent qui détient les clés, la localisation des données et la sortie (voir clauses contrat prestataire tech et RGPD freelances et registre DPA)
Test rapide côté attaquant (15 minutes)
À faire depuis l'extérieur de votre réseau bureau, comme un inconnu sur Internet.
- Ouvrir
https://votre-domaine-odoo/web/database/manager. Vous ne devez pas obtenir un écran d'administration des bases - Tenter de lister les bases sur
/web/database/selector. Aveclist_db = False, attendez un refus ou un flux connexion seulement - Tester des mots de passe évidents sur un compte test que vous contrôlez, pas sur de vrais utilisateurs. Si la politique autorise des mots faibles, corrigez la politique avant que d'autres essaient
- Avec un scan de ports de confiance, vérifier que PostgreSQL et Redis ne sont pas ouverts au monde
- Chercher des hostnames de staging ou anciennes URL projet pointant encore vers une copie de production
- Repérer fichiers de sauvegarde, dumps
.sqlou archives.zipsous la racine web ou un chemin devinable - Se connecter avec un utilisateur peu privilégié créé pour le test. Confirmer l'impossibilité d'ouvrir compta, gestion utilisateurs ou RIB fournisseur non autorisés
Chaque « oui, ça a marché » ouvre un ticket, pas un débat.
Erreurs fréquentes
- Production joignable avec
list_db = Trueet mot de passe maître vide - Un mot de passe administrateur partagé dans un canal de chat
- Intégrateur laissé superutilisateur permanent après go-live
- Des dizaines d'apps installées, moitié inutilisées, jamais mises à jour
- Dump base chaque nuit mais aucune sauvegarde filestore
- Clone staging de production sur URL publique sans restriction IP
- PostgreSQL exposé « temporairement » et oublié
- Règles d'enregistrement supposées correctes parce que « on n'utilise que du standard »
- Aucun test de restauration depuis le déploiement initial
- Domaine et hébergement payés par l'agence, compte au nom de l'agence
Checklist
list_db = False, mot de passe maître fort,dbfilterdéfini- Gestionnaire de bases bloqué ou restreint par IP au proxy
- Inventaire modules documenté, apps inutilisées retirées ou planifiées
- Versions Odoo, OS, Python et PostgreSQL supportées, routine de correctifs définie
- Utilisateurs nominatifs, gestionnaire de mots de passe, 2FA sur comptes privilégiés
- Groupes et règles relus, pas d'administrateurs Paramètres par habitude
- HTTPS avec certificats surveillés, PostgreSQL non public
- Base et filestore sauvegardés hors serveur, restauration testée
- Surveillance disponibilité, disque et échecs d'authentification
- Hébergement, DNS et sauvegardes possédés par l'entreprise, accès intégrateur limité dans le temps
Besoin d'aide pour durcir Odoo en production ?
Décrivez édition, hébergement, modules et qui a accès. On vous proposera les prochaines étapes raisonnables.