[development] Making #access required on forms
Larry Garfield
larry at garfieldtech.com
Fri Oct 24 16:31:10 UTC 2008
On Fri, 24 Oct 2008 12:00:33 -0400, Angela Byron <drupal-devel at webchick.net> wrote:
> Gerhard brought this up on the security team list, but it seems like
> it's worth broader discussion:
>
> ---
>
> Hi there,
>
> as more an more people use Drupal to provide non-traditional Webpages
> (e.g. providing services using Ajax, Flex, ...) our traditional access
> permission checks in hook_menu are less than ideal.
>
> For example, you can use drupal_execute to conveniently create content
> or anything else. However, no check for access permissions is done since
> this only happens in the menu hook for node/add/whatever.
>
> I therefore propose to push for D7 that the #access parameter on forms
> be made mandatory.
>
> Opinions?
>
> ---
>
> My initial thought on the downside is that this has implications for
> people who are using drupal_execute() to perform programmatic tasks
> (node/block/etc. creation, etc.); they would no longer work unless the
> script switched to user with the proper credentials (so we should
> probably get a nice user switching API function in core). It is also
> something in the upgrade steps that, if missed, will cause forms to
> completely disappear which is bound to result in support requests.
>
> On the other hand, it would provide extra security and would be akin to
> the way we force menu callbacks to provide an access control or they
> don't appear for anyone. It might also help us clean up some nasty
> places in core (node form, I am looking at you) where we have if
> (user_access(...)) hard-coded.
>
> So, I echo: opinions? :)
>
> -Angie
I have long argued that any part of a form that should only appear for some users should *always* be added, and then controlled with #access, and the validate and submit handlers must be designed to handle either case regardless of permission settings. That makes forms much easier to form_alter in useful ways. I've been bitten by modules not doing that, or not being able to handle a form value that is #access = FALSE, way too many times, especially by OG. We may need to tweak the internals of FAPI a little so that it handles #access = FALSE in a consistent manner to make the submit hooks easier.
Of course, having to specify #access everywhere would be a nightmare.
So I'd propose:
- *All* FAPI/drupal_render() elements must support #access. A validate/submit callback that does not function properly with #access set true or false is by definition buggy.
- All elements define whether #access defaults to TRUE or FALSE if not specified.
- For the main form itself, #access defaults to FALSE. For everything else, it defaults to TRUE.
- Establish a standard to handle conditional form adds via #access, not via an if statement. Using an if(user_access()) is treated as a bug. If that causes bugs anywhere, then the bugs get fixed per the first item.
- Document the hell out of the above so that people know the Power of the #Access side.
Does that sound like a reasonable balance? In the degenerate case for a typical form, it's one extra line to add an #access => TRUE or #access => user_access() to each form.
Of course, one alternative is to have an #access_callback and #access_arguments property pair a la menu API, but I don't know if that's overkill. :-)
--Larry Garfield
More information about the development
mailing list