I have set up a profile for each role so that role X can only view users with role X's profiles. So in the permissions page I gave Role X permissions to view Any Role X profile and no permission to view Role Y profile.
This permission does not seem to be making effect since users with Role X can still see Role Y profile and vice versa. Is this a bug or am I doing something wrong?
Thanks,
Spre3

Comments

ericbroder’s picture

Priority: Normal » Critical
Issue tags: +Security improvements

There appears to be a significant risk of exposing sensitive data. I tested on a standard D7 install. Even with both of these permissions turned off:

- Profile Name: View own profile
- Profile Name: View any profile

...users can still view their own Profile Name profile. This potentially exposes sensitive data and appears to be a "Less Critical" Security Risk: http://drupal.org/security-team/risk-levels

Drupal version or module version:

- Drupal core 7.0
- Profile 2 7.x-1.x
- Entity 7.x-1.x

Steps to reproduce:

- Install Drupal with a Standard Install Profile.
- Install and Enable Profile 2 and Entity modules.
- Create a new profile and turn off "View own" and "View any" permissions.
- Test if a user can view their own profile data.
- Expected result based on permissions is that user can not view their own profile data.

I contacted the Drupal Security Team, and they said:

After careful review, this vulnerability can be fixed publicly as per http://drupal.org/security-advisory-policy because it affects a branch (or branches) of a project that does not have a "stable release"

greggles’s picture

Subscribe.

rwohleb’s picture

My issue is that I'm trying to pull in profile2 fields into views. It works great... as long as you are admin.

It looks like the issue (my part of it at least) is coming from two directions. First, profile2_field_access() isn't checking much of the available state. It's relying on the full entity being passed, which is really an optional argument to hook_field_access. This would be fine, except it's returning FALSE any time the entity is missing, even when the target field is not set as private and doesn't need to check the UID attached to the entity.

The other side of the issue appears to be coming from views. The access() method of views_handler_field_field is calling field_access(), but is just passing the field name instead of a full field array. All the docs I've found, including field.api.php, gives an example with $field being an array.

Am I on crack?

matt2000’s picture

subscribe

joachim’s picture

Confirming.

At /user/X I can see a heading and field output for a profile type where *nobody* has any permissions. This happens both for the user viewing their own profile, and for anons (where they can see the user profile in general).

ericbroder’s picture

Status: Needs review » Active

I assume the security check is supposed to happen here:

/**
 * Determines whether the given user has access to a profile.
 *
 * @param $op
 *   The operation being performed. One of 'view', 'update', 'create', 'delete'
 *   or just 'edit' (being the same as 'create' or 'update').
 * @param $profile
 *   Optionally a profile or a profile type o check access for. If nothing is
 *   given, access for all profiles is determined.
 * @param $account
 *   The user to check for. Leave it to NULL to check for the global user.
 * @return boolean
 *   Whether access is allowed or not.
 */
function profile2_access($op, $profile = NULL, $account = NULL) {
  if (user_access('administer profiles', $account)) {
    return TRUE;
  }
  if (isset($profile) && $type_name = $profile->type) {
    if ($op == 'delete') {
      return FALSE;
    }
    $op = ($op == 'view') ? 'view' : 'edit';
    if (user_access("$op any $type_name profile", $account)) {
      return TRUE;
    }
    $account = isset($account) ? $account : $GLOBALS['user'];
    if (isset($profile->uid) && $profile->uid == $account->uid && user_access("$op own $type_name profile", $account)) {
      return TRUE;
    }
  }
  return FALSE;
}

ref: http://drupalcode.org/project/profile2.git/blob/refs/heads/7.x-1.x:/prof...

However when I check this in my debugger, it looks like this function is not actually being called when a user views their own profile.

The main place I see profile2_access called is in hook_entity_info:

/**
 * Implements hook_entity_info().
 */
function profile2_entity_info() {
  $return = array(
    'profile2' => array(
      'label' => t('Profile'),
      'entity class' => 'Profile',
      'controller class' => 'EntityAPIController',
      'base table' => 'profile',
      'fieldable' => TRUE,
      'view modes' => array(
        'account' => array(
          'label' => t('User account'),
          'custom settings' => FALSE,
        ),
      ),
      'entity keys' => array(
        'id' => 'pid',
        'bundle' => 'type',
      ),
      'bundles' => array(),
      'bundle keys' => array(
        'bundle' => 'type',
      ),
      'label callback' => 'entity_class_label',
      'uri callback' => 'entity_class_uri',
      'access callback' => 'profile2_access',
      'module' => 'profile2',
      'metadata controller class' => 'Profile2MetadataController'
    ),
  );
  $return['profile2_type'] = array(
    'label' => t('Profile type'),
    'entity class' => 'ProfileType',
    'controller class' => 'EntityAPIController',
    'base table' => 'profile_type',
    'fieldable' => FALSE,
    'bundle of' => 'profile2',
    'exportable' => TRUE,
    'entity keys' => array(
      'id' => 'id',
      'name' => 'type',
      'label' => 'label',
    ),
    'access callback' => 'profile2_type_access',
    'module' => 'profile2',
    // Enable the entity API's admin UI.
    'admin ui' => array(
      'path' => 'admin/structure/profiles',
      'file' => 'profile2.admin.inc',
      'controller class' => 'Profile2TypeUIController',
    ),
  );
  return $return;
}

ref: http://drupalcode.org/project/profile2.git/blob/refs/heads/7.x-1.x:/prof...

UPDATE: Sorry, this was incorrect: ...it looks like this function is not actually being called when a user views their own profile. I think I was having a problem with my debugger. The real problem seems to be that the function is not called with $op = view, so it doesn't really check the View own and View any permissions.

joachim’s picture

Status: Active » Needs review
StatusFileSize
new499 bytes

Thanks for the digging work :)
Looks like this will be a nice and simple patch... can anyone test it?

joachim’s picture

Status: Needs review » Needs work

Hmm. That call should not pass in $account.

But it's getting pretty late here... perhaps someone else can reroll? :)

ericbroder’s picture

Status: Needs work » Needs review
StatusFileSize
new489 bytes

Rerolled patch based on #1051550-8: users always see their own profiles. Seems to work, though I'm not much of a hook_user_view expert: http://api.drupal.org/api/drupal/modules--user--user.api.php/function/ho...

ericbroder’s picture

Status: Active » Needs review
roam2345’s picture

closed duplicate #1149808: Field permission issues when using relationships. to track on this thread.

Application of patch #7 and #9 did not resolve the issue for me so far.

My issue is from a different angle but essentially the same thing.

I have a view that does the following (using a block).
- I get the UID off the url (contextual filter)
- I add the relationship with the profile for the user.
- I try and show any field off the profile (using the relationship).
- Set the view access permissions to (None) or (permission | View published content) has same effect.
- BOOM! I can view the block as an admin, but anon that has permission to view the profile gets a funky error (see link at top).

joachim’s picture

This issue is about the core display of profile categories at /user/UID.

Showing stuff in a View is another matter entirely -- I suggest you reopen that other issue and change its tile so it's clearly stated it concerns fields shown in Views.

roam2345’s picture

@joachim kk thanks. From my understanding of views access permissions the error is propagating from this issue, but ill leave that for comment on the other thread.

karilu_ec’s picture

Patch didn't work for me either. I have a view that displays the profile of the a person in a role 'staff', I created the view for a personnel page.
I can see the page as an admin but I cannot see the page as anonymous user or even the own person of the staff that is seeing that page (view). Similar issue as post #11 in the closed duplicate issue.

fago’s picture

Title: View profile permissions not working » users always see their own profiles
Status: Needs review » Needs work
Issue tags: +Needs tests

ouch.

Patch solve the issue, however we should better not create the render-array at all if it cannot be viewed anyway. Also, we should add tests to this so it cannot happen again.

fago’s picture

Status: Needs work » Needs review
StatusFileSize
new2.2 KB
fago’s picture

Status: Needs review » Fixed

I've committed that patch + added some improvements to profile2_access() so modules may alter access. Please test carefully and report any problems.

fago’s picture

Any feedback? Does no one care?

ericbroder’s picture

Thanks fago, this issue appears to be fixed now: #1051550-1: users always see their own profiles

Tested on:
- Drupal core: 7.2
- Profile 2: 7.x-1.x
- Entity: 7.x-1.x

fago’s picture

thanks, I published a new release containing the fix: http://drupal.org/node/1181018

Status: Fixed » Closed (fixed)
Issue tags: -Security improvements, -Needs tests

Automatically closed -- issue fixed for 2 weeks with no activity.