Duration: 26:08
PART 1 — Analytical Summary 🚀
Context 💼
This 26-minute technical talk is a hands-on follow-up to a broader security session given earlier in the day. The speaker (an Odoo developer/security reviewer) walks through real-world vulnerabilities seen in community modules, Odoo App Store add-ons, and even older internal code. The goal is to teach Odoo developers and solution builders how to avoid common pitfalls that create critical attack surfaces — using concrete examples that were actually found and fixed.
Core ideas & innovations 🧠
The session opens with a foundational concept: in Odoo, model method visibility drives your attack surface. Methods prefixed with an underscore are private, callable only internally; anything else is public and accessible via XML-RPC/JSON-RPC. The rule of thumb: default everything to private, and only remove the underscore when truly necessary — after re-reviewing the code for sudo usage and side effects. A seemingly benign public method that starts with a blanket sudo can let a mere portal user escalate to admin. One real example from the App Store effectively exposed a raw SQL API over HTTP, allowing arbitrary SELECT/UPDATE/INSERT — a direct line to total database compromise.
Next, the talk addresses SQL safety. While Odoo gives direct cursor access, the ORM exists to prevent mistakes. Building SQL with Python f-strings or naive templating invites SQL injection — the speaker demonstrates how an attacker could terminate the previous clause, inject their own query, and exfiltrate password hashes or reset the admin’s credentials. Since Odoo 17, developers are expected to use the SQL wrapper (instead of raw cr.execute parameterization) because it safely escapes identifiers (table/column names) as well as values. Odoo’s CI security rules enforce correct usage — the first SQL wrapper argument must be a static string to prevent injection through string interpolation.
The third pillar is “don’t over-sudo.” A classic trap is reading user-submitted payloads in a controller and passing them straight to a sudo write — effectively allowing a user to edit any writable field on themselves, from HTML descriptions (ripe for phishing links) to other sensitive text fields. The fix is to whitelist exactly which fields can be updated (e.g., display name, email), never accept arbitrary field dicts, and add a second reviewer whenever sudo appears. A related sharp edge is the use of related fields to attachments: related fields read as sudo, so a user who can point a Many2one to any ir.attachment can read its content — potentially exposing payslips or contracts. Prefer a fields.Binary (which auto-creates attachments but correctly enforces ACLs) or fetch attachments via controlled searches on res_model and res_id.
The last major section clarifies access rights (ACLs) vs. record rules. ACLs grant table-level permissions (read/write/create/unlink), while record rules restrict which records those permissions apply to. Global rules (no groups) are combined with AND; group-based rules combine with OR. A subtle misuse — e.g., giving a portal user full read ACL while having no effective read record rule — can let attackers iterate IDs and dump email addresses or other sensitive data via related fields. The speaker also flags domain injection: when enforcing a domain, use a domain “AND” combiner (in v18 it’s expression.AND) so users cannot cancel your forced domain with a crafted filter.
Throughout, the speaker emphasizes Odoo’s defense-in-depth: CI checks for SQL safety, framework-level protections, and a disciplined review culture. For third-party apps outside Odoo/OCA code reviews, penetration testing is strongly recommended.
Impact & takeaways ⚙️
This talk distills hard-earned lessons into practical guardrails that materially reduce risk:
- Default model methods to private; only expose what you must, and re-review security when you do.
- Favor the Odoo ORM; if you must write SQL, use the SQL wrapper introduced in Odoo 17 and pass only static strings as the base query.
- Treat sudo as hazardous: whitelist fields, avoid arbitrary payloads, and always double-review sudo code paths.
- Avoid related fields to attachments; prefer fields.Binary or controlled queries on
ir.attachment. - Understand ACLs vs. record rules; ensure every granted ACL has an effective record rule, and use safe domain composition to prevent domain injection.
- Rigorously review third-party modules; rely on OCA or Odoo-reviewed code when possible; otherwise, use external pen testing.
- In reviews, watch for telltales like
cr.execute,sudo, related fields pointing to sensitive models, public methods, and domain builders.
Q&A highlights 💬:
On AI/LLMs, Odoo limits data exposure (e.g., only passing folder names for document sorting) and currently trusts external models like ChatGPT and Gemini, with privacy options enabled where available. Full anonymization for message/email summarization is complex in practice. On migrations, the same SQL safety checks apply. For stronger authentication, you can force TOTP at the system level (email-based if app TOTP isn’t set); there’s no universal enforcement for app-based TOTP. For attachments, replace risky related fields with fields.Binary or explicit searches on ir.attachment. Slides will be made available via the session description; remaining questions will be answered asynchronously.
Reviewer triggers to pause and reassess:
cr.executeor hand-built SQL- Any use of
sudo - Related fields to sensitive models (especially
ir.attachment) - Public model methods (no underscore)
- Domain composition without explicit AND-combining
PART 2 — Viewpoint: Odoo Perspective
Disclaimer: AI-generated creative perspective inspired by Odoo’s vision.
Security must feel simple, or it won’t be applied consistently. What I appreciate in this talk is how the framework itself — ORM, SQL wrapper, CI checks — carries much of the burden. If we nudge developers to start with private methods, avoid sudo by default, and rely on the ORM, we shrink the attack surface without slowing teams down.
The community is our strength. We’ll keep raising the bar on reviews, making secure defaults the easiest path, and sharing patterns publicly. Integration, not complexity, is our north star — the more we make the “right way” the “easy way,” the safer every Odoo deployment becomes.
PART 3 — Viewpoint: Competitors (SAP / Microsoft / Others)
Disclaimer: AI-generated fictional commentary. Not an official corporate statement.
The session shows commendable rigor: CI-enforced SQL practices, clear guidance on ACLs vs. record rules, and pragmatic advice on sudo. For mid-market deployments, these guardrails are valuable. At enterprise scale, the challenge remains consistency across partner ecosystems and customizations — especially where regulatory compliance (SOX, GDPR, industry certifications) demands formalized controls, segregation of duties, and provable auditability.
UX simplicity is a differentiator for Odoo, but large organizations will scrutinize identity/SSO mandates, multi-factor enforcement options, and policy-as-code coverage across modules. The direction is right; winning complex, global rollouts hinges on strong defaults paired with verifiable, centralized governance for custom code and third-party add-ons.
Disclaimer: This article contains AI-generated summaries and fictionalized commentaries for illustrative purposes. Viewpoints labeled as "Odoo Perspective" or "Competitors" are simulated and do not represent any real statements or positions. All product names and trademarks belong to their respective owners.