Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REF] base: safe_eval rewrite using AST #75

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ghost
Copy link

@ghost ghost commented Apr 25, 2024

Context

safe_eval is Odoo's sandbox, this mechanism allows users and developpers to write templates, server actions, and more without worrying about the security risks associated with arbitrary code execution.

The current version of the sandbox heavily relies on Python's bytecodes and compile-time verifications. This causes 2 major problems:

  1. In every release of Python, its bytecodes are updated or modified.
    Which makes Odoo unusable until the security / framework team updates the
    whitelist of bytecode.

  2. Most sandboxing issues we have faced for the last years was due to a
    lack of runtime checks (functions inputs (arguments) and outputs
    (return values)). All most every times those kind of issues were
    fixed with "dirty" hacks such as adding a list of
    "unsafe attribute" or adding a wrapper for modules that are exposing
    unsafe objects (such as the sys module)

Goal of the change

During this rewrite we had a few goals:

  1. Retain compatibility with the original version:

    • Find a way to keep the old checks (deny dunders, attribute storing
      and deleting)
    • Keep the same exposed API, limiting the amount of code that needs
      to be rewritten as much as possible
  2. Add runtime checks to verify that every types passed and returns are
    safe by checking their type. The way that the sandbox does it is by
    using two set of types. One for the types we allow to instanciate
    (the ones that we have absolute trust, most of them are primitive
    types such as str and int) and the ones that we only allow as
    instance, this means that you CANNOT instanciate them inside of the
    sandbox (for example the sql cursor or the Odoo environement).

  3. Eliminate the issues with the .format and .format_map.
    This is a well known issue within the Python security community, if
    you want more info : https://lucumr.pocoo.org/2016/12/29/careful-with-str-format/

--
See odoo/odoo#138611 odoo/enterprise#48919 odoo/upgrade#5653

@robodoo
Copy link
Contributor

robodoo commented Apr 25, 2024

@ghost ghost force-pushed the master-safe_eval_redo-joda branch from db008b3 to 89e9aa1 Compare April 26, 2024 08:22
@@ -207,7 +207,11 @@ def _adapt_one_domain(cr, target_model, old, new, model, domain, adapter=None, f
# pre-check domain
if isinstance(domain, basestring):
try:
eval_dom = expression.normalize_domain(safe_eval(domain, evaluation_context, nocopy=True))
if version_gte("saas~17.2"):
eval_dom = expression.normalize_domain(safe_eval(domain, locals_dict=evaluation_context))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why passing the evaluation_context as locals_dict in this case?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iirc, if you pass it in the globals it will break.

Comment on lines 1151 to 1154
if version_gte("saas~17.2"):
context = safe_eval(act.get("context", "{}"), eval_context, nocopy=True)
else:
context = safe_eval(act.get("context", "{}"), eval_context, nocopy=True)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No difference?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I'll remove it

@ghost ghost force-pushed the master-safe_eval_redo-joda branch 2 times, most recently from 22fa28d to a88fcb2 Compare May 6, 2024 06:56
@KangOl
Copy link
Contributor

KangOl commented May 6, 2024

upgradeci retry with always only base hr in 17.0 master

@ghost ghost force-pushed the master-safe_eval_redo-joda branch from a88fcb2 to 8a9ff1f Compare May 8, 2024 12:17
Context
=======

`safe_eval` is Odoo's sandbox, this mechanism allows users and
developpers to write templates, server actions, and more without
worrying about the security risks associated with arbitrary code execution.

The current version of the sandbox heavily relies on Python's bytecodes
and compile-time verifications. This causes 2 major problems:

1) In every release of Python, its bytecodes are updated or modified.
   Which makes Odoo unusable until the security / framework team updates the
   whitelist of bytecode.

2) Most sandboxing issues we have faced for the last years was due to a
   lack of runtime checks (functions inputs (arguments) and outputs
   (return values)). All most every times those kind of issues were
   fixed with "dirty" hacks such as adding a list of
   "unsafe attribute" or adding a wrapper for modules that are exposing
   unsafe objects (such as the `sys` module)

Goal of the change
==================

During this rewrite we had a few goals:

1) Retain compatibility with the original version:
    * Find a way to keep the old checks (deny dunders, attribute storing
      and deleting)
    * Keep the same exposed API, limiting the amount of code that needs
      to be rewritten as much as possible

2) Add runtime checks to verify that every types passed and returns are
   safe by checking their type. The way that the sandbox does it is by
   using two set of types. One for the types we allow to instanciate
   (the ones that we have absolute trust, most of them are primitive
   types such as `str` and `int`) and the ones that we only allow as
   instance, this means that you CANNOT instanciate them inside of the
   sandbox (for example the sql cursor or the Odoo environement).

3) Eliminate the issues with the `.format` and `.format_map`.
   This is a well known issue within the Python security community, if
   you want more info : https://lucumr.pocoo.org/2016/12/29/careful-with-str-format/
@ghost ghost force-pushed the master-safe_eval_redo-joda branch from 8a9ff1f to 6d34f37 Compare May 14, 2024 06:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants