From 2cf2b8cb6f5322a121bba6d9eef2e4ab8819b05a Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Mon, 4 Oct 2021 10:08:29 +0000 Subject: [PATCH] [FIX] payment: fix access error in tx processing The `callback_hash` and `callback_is_done` fields are not accessible for non-admin users, so it will cause an access error whenever trying to verify the hash inside `_execute_callback()`, and when marking the callback execution successful. Accessing it as `sudo` like other restricted transaction fields solves the problem, and is safe, as the value is never leaked outside the function. Introduced in 573ed74c121c1572b3fab6f9553ed7f93f7b3f99. closes odoo/odoo#77737 X-original-commit: 743031ed400b26f05775fc01c04ff63ef597a723 Signed-off-by: Antoine Vandevenne (anv) --- addons/payment/models/payment_transaction.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/addons/payment/models/payment_transaction.py b/addons/payment/models/payment_transaction.py index 2e2540c8292..3b4478c94be 100644 --- a/addons/payment/models/payment_transaction.py +++ b/addons/payment/models/payment_transaction.py @@ -770,14 +770,16 @@ class PaymentTransaction(models.Model): """ for tx in self.filtered(lambda t: not t.sudo().callback_is_done): # Only use sudo to check, not to execute - model_sudo = tx.sudo().callback_model_id - res_id = tx.sudo().callback_res_id - method = tx.sudo().callback_method + tx_sudo = tx.sudo() + model_sudo = tx_sudo.callback_model_id + res_id = tx_sudo.callback_res_id + method = tx_sudo.callback_method + callback_hash = tx_sudo.callback_hash if not (model_sudo and res_id and method): continue # Skip transactions with unset (or not properly defined) callbacks valid_callback_hash = self._generate_callback_hash(model_sudo.id, res_id, method) - if not consteq(ustr(valid_callback_hash), tx.callback_hash): + if not consteq(ustr(valid_callback_hash), callback_hash): _logger.warning("invalid callback signature for transaction with id %s", tx.id) continue # Ignore tampered callbacks @@ -795,7 +797,7 @@ class PaymentTransaction(models.Model): continue # Ignore invalidated callbacks success = getattr(record, method)(tx) # Execute the callback - tx.callback_is_done = success or success is None # Missing returns are successful + tx_sudo.callback_is_done = success or success is None # Missing returns are successful #=== BUSINESS METHODS - POST-PROCESSING ===#