You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2026/05/26 20:56:23 UTC
(allura) 07/33: [#8607] check app_config_id in update_forums
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch db/8607
in repository https://gitbox.apache.org/repos/asf/allura.git
commit b77f66002d3adf3eae404988aef9a3874dd63db4
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Fri May 15 16:51:36 2026 -0400
[#8607] check app_config_id in update_forums
---
ForgeDiscussion/forgediscussion/forum_main.py | 5 ++-
.../tests/functional/test_forum_admin.py | 36 ++++++++++++++++++++++
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/ForgeDiscussion/forgediscussion/forum_main.py b/ForgeDiscussion/forgediscussion/forum_main.py
index 9ab89f4c6..2c70cd47b 100644
--- a/ForgeDiscussion/forgediscussion/forum_main.py
+++ b/ForgeDiscussion/forgediscussion/forum_main.py
@@ -322,7 +322,10 @@ def set_value(forum, name, val):
setattr(forum, name, val)
for f in forum:
- forum = DM.Forum.query.get(_id=ObjectId(str(f['id'])))
+ forum = DM.Forum.query.get(_id=ObjectId(str(f['id'])),
+ app_config_id=self.app.config._id)
+ if forum is None:
+ continue
if f.get('delete'):
forum.deleted = True
M.AuditLog.log('deleted forum "{}" from {}'.format(
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py
index 72cf633d5..459f2c91a 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py
@@ -18,9 +18,12 @@
import logging
import re
+from ming.odm import ThreadLocalODMSession
+from tg import tmpl_context as c
from alluratest.controller import TestController
from allura.lib import helpers as h
from allura import model as M
+from allura.tests import decorators as td
from forgediscussion import model as FM
@@ -320,3 +323,36 @@ def test_footer_monitoring_email(self):
0].kwargs['text'], email_tasks[0].kwargs['text']
assert 'a project admin can change settings at http://localhost/p/test/admin/discussion/forums' in email_tasks[
0].kwargs['text']
+
+ @td.with_tool('test2', 'Discussion', 'discussion')
+ def test_update_forums_rejects_foreign_forum(self):
+ # Create a forum in the test2 project's Discussion app (the victim).
+ h.set_context('test2', 'discussion', neighborhood='Projects')
+ victim_app_config_id = c.app.config._id
+ victim = FM.Forum(
+ app_config_id=victim_app_config_id,
+ shortname='victim',
+ name='Victim Forum',
+ description='original',
+ )
+ ThreadLocalODMSession.flush_all()
+ victim_id = victim._id
+
+ # Attacker is admin of project 'test' and posts to its update_forums with the victim's _id.
+ self.app.post('/admin/discussion/update_forums',
+ params={'forum-0.delete': 'on',
+ 'forum-0.id': str(victim_id),
+ 'forum-0.name': 'Pwned',
+ 'forum-0.shortname': 'pwned',
+ 'forum-0.description': 'pwned',
+ 'forum-0.monitoring_email': ''})
+
+ # Victim forum in test2 must be untouched.
+ ThreadLocalODMSession.close_all()
+ h.set_context('test2', 'discussion', neighborhood='Projects')
+ reloaded = FM.Forum.query.get(_id=victim_id)
+ assert reloaded is not None
+ assert reloaded.deleted is False, 'foreign forum was deleted via cross-project update_forums'
+ assert reloaded.name == 'Victim Forum', 'foreign forum was renamed via cross-project update_forums'
+ assert reloaded.description == 'original'
+ assert reloaded.app_config_id == victim_app_config_id