Articles · Odoo

2027-08-05 12 min EN / FR

Securing an Odoo instance: users, access rights, backups and exposure

Odoo holds customers, suppliers, payroll hints and stock worth real money. Most incidents are not exotic zero-days. They come from a database manager left open on the internet, too many installed apps, shared administrator passwords, or backups that omit the filestore. A secure Odoo setup is a short list applied consistently on production.

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 = False in odoo.conf so anonymous visitors cannot list databases
  • Use dbfilter so 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/manager and /web/database/selector at 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 .git from 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/login from 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. With list_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, .sql dumps or .zip archives 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 = True and 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, dbfilter set
  • 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

Related

Want help hardening production Odoo?

Describe your edition, hosting, modules and who has access. We will suggest sensible next steps.