Setting '#access' = FALSE in #after_build, only hides the element, it does not protect it from being posted. End user is still able to post data, i.e. manually alter the client-side code, insert <input type="text" id="edit-path-alias" name="path[alias]" value="" size="60" maxlength="255" class="form-text"> and post data.

Example:
The code below, sets Path Alias #access to FALSE, yet you're still able to post Path Alias by altering client-side code.

<?php
function mymodule_form_alter(&$form, &$form_state){
  if (empty($form['type']['#value'])) return;
  $form['#after_build'][] = 'mymodule_after_built';
}

function mymodule_after_built($form, &$form_state) {
  $form['path']['#access'] = FALSE;
   return ($form);
}

Comments

timofey’s picture

Title: #access setting not working in #after_build » #access setting not fully working in #after_build
timofey’s picture

Title: #access setting not fully working in #after_build » #access setting not working in #after_build
dokumori’s picture

Status: Active » Closed (works as designed)

In form.inc, it says:

Forms that set access=FALSE on an element usually allow access for some users, so forms submitted with drupal_form_submit() may bypass access restriction and be treated as high-privilege users instead.

I tested this locally and can confirm a form element can indeed be injected by client using tools such as FireBug, but it is designed this way. If a user doesn't have the privilege to edit a field whose content s/he is trying to alter, it won't let her/him edit the field content by injecting the HTML form element (tested with Path module, as well as Field Permissions module) so I don't see any security risk here.

timofey’s picture

Status: Closed (works as designed) » Active

On the contrary, description on Forms API says:

Whether the element is accessible or not; when FALSE... ...the user submitted value is not taken into consideration.

To my knowledge, no other condition in which Form is set to #access = FALSE, allow code ejection on the client side by tools such as FireBug. For example, if you try setting #access = FALSE in hook_node_alter() or drupal_get_form(), it will not allow injections. #after_built is the only condition that allows code ejection with #access = FALSE.

I'm setting this to active for another opinion.

Version: 7.33 » 7.x-dev

Core issues are now filed against the dev versions where changes will be made. Document the specific release you are using in your issue comment. More information about choosing a version.