Change URL on ajax call, but enforce access checks?
Hi, I'm trying to understand what is the best way to supply URL based content through Ajax, without compromising on security and access control. When the user clicks on the widget, an ajax URL is called upon and served by a menu callback (e.g. http://example.com/myajax). I'd like to also relate to the URL that the widget is displayed upon. This is easily achieved by using a GET parameter on the ajax URL (e.g. http://example.com/myajax?referer=user/2) The myajax callback might call other functions in the system that use argument checking (e.g. arg(0) == 'user' && is_numeric(arg(1) )). This is necessary if I want to use the same functions to generate content for the non-JS version. Therefore, I set: <?php $_GET['q'] = $_GET['referer']; ?> before calling those other functions. Assuming I don't know anything about those "other functions", this looks to me like a security risk. Since the whole access sub-system is using 'myajax' as the path for access checks. Those "other functions" might assume that access checks where already ran by Drupal subsystem, which I just bypassed. Can you see a better way to implement this? maybe I should check _menu_item_is_accessible(menu_set_active_item($_GET['referer']))? It seems to work but looks a bit hackish to me... Any help will be appreciated, Thanks, -- Yuval Hager [T] +972-77-341-4155 [@] yuval@avramzon.net
arg() checking is discouraged in modern drupal for this very reason. each drupal release we have been able to get rid of more of them in core and with the D6 menu system, I really doubt we need any of these calls to arg(). contrib modules that use arg() for access control should refactor and let the menu system handle access control. your workaround looks fine if it works and has no side effects. needs testing.
On Sunday 01 June 2008, Moshe Weitzman wrote:
arg() checking is discouraged in modern drupal for this very reason. each drupal release we have been able to get rid of more of them in core and with the D6 menu system, I really doubt we need any of these calls to arg(). contrib modules that use arg() for access control should refactor and let the menu system handle access control.
your workaround looks fine if it works and has no side effects. needs testing.
It looked like it was working in most cases, but there is a certain case where it fails. If user with uid==1 (admin) is browsing the site, running: <?php menu_set_active_item('user/2'); if (!_menu_item_is_accessible(menu_get_active_item())) { drupal_access_denied(); } ?> gets me access denied every time. I tried to follow the code using a debugger, but can't get my head around the structure of $menu. Any idea how to get the access checking results correctly here? (btw, this is Drupal 5.x) -- Yuval Hager [T] +972-77-341-4155 [@] yuval@avramzon.net
participants (2)
-
Moshe Weitzman -
Yuval Hager