From 1b51327bfb7369a9f0971260c75b99d499a855c9 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Mon, 8 Oct 2018 10:04:36 +0200 Subject: [PATCH] Prevent to send web notifications to other users Only the admin user (sudo) is allowed to send notifications to other users. The normal users can only send notifications to themselves. This is to prevent attackers to craft malicious notifications and send them to other users using RPC. Correction based on the idea of @hbrunn --- web_notify/models/res_users.py | 7 ++++++- web_notify/tests/test_res_users.py | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/web_notify/models/res_users.py b/web_notify/models/res_users.py index 511474557869..cac735445bef 100644 --- a/web_notify/models/res_users.py +++ b/web_notify/models/res_users.py @@ -2,7 +2,7 @@ # Copyright 2016 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from openerp import api, fields, models, _ +from openerp import api, exceptions, fields, models, _, SUPERUSER_ID class ResUsers(models.Model): @@ -36,6 +36,11 @@ def notify_warning(self, message, title=None, sticky=False): @api.multi def _notify_channel(self, channel_name_field, message, title, sticky): + if (self.env.uid != SUPERUSER_ID + and any(user.id != self.env.uid for user in self)): + raise exceptions.UserError( + _('Sending a notification to another user is forbidden.') + ) bus_message = { 'message': message, 'title': title, diff --git a/web_notify/tests/test_res_users.py b/web_notify/tests/test_res_users.py index d32bc71b3adc..e85cf7908e24 100644 --- a/web_notify/tests/test_res_users.py +++ b/web_notify/tests/test_res_users.py @@ -2,6 +2,7 @@ # Copyright 2016 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from openerp import exceptions from openerp.tests import common from openerp.addons.bus.models.bus import json_dump import mock @@ -49,3 +50,13 @@ def test_notify_many(self): users.notify_warning('message') self.assertEqual(1, mockedSendMany.call_count) self.assertEqual(len(users), len(mockedSendMany.call_args[0][0])) + + def test_notify_other_user(self): + other_user = self.env.ref('base.user_demo') + other_user_model = self.env['res.users'].sudo(other_user) + with self.assertRaises(exceptions.UserError): + other_user_model.browse(self.env.uid).notify_info('hello') + + def test_notify_admin_allowed_other_user(self): + other_user = self.env.ref('base.user_demo') + other_user.notify_info('hello')