security update core 7.58

This commit is contained in:
2018-04-24 23:33:29 +02:00
parent 3d293a3de5
commit 3d5c5ad2f6
166 changed files with 1633 additions and 480 deletions
+3 -3
View File
@@ -6,8 +6,8 @@ core = 7.x
dependencies[] = field
files[] = tests/file.test
; Information added by Drupal.org packaging script on 2017-02-01
version = "7.54"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1485986921"
datestamp = "1522264019"
+18 -5
View File
@@ -140,14 +140,15 @@ function file_file_download($uri, $field_type = 'file') {
}
// Find out which (if any) fields of this type contain the file.
$references = file_get_file_references($file, NULL, FIELD_LOAD_CURRENT, $field_type);
$references = file_get_file_references($file, NULL, FIELD_LOAD_CURRENT, $field_type, FALSE);
// Stop processing if there are no references in order to avoid returning
// headers for files controlled by other modules. Make an exception for
// temporary files where the host entity has not yet been saved (for example,
// an image preview on a node/add form) in which case, allow download by the
// file's owner.
if (empty($references) && ($file->status == FILE_STATUS_PERMANENT || $file->uid != $user->uid)) {
// file's owner. For anonymous file owners, only the browser session that
// uploaded the file should be granted access.
if (empty($references) && ($file->status == FILE_STATUS_PERMANENT || $file->uid != $user->uid || (!$user->uid && empty($_SESSION['anonymous_allowed_file_ids'][$file->fid])))) {
return;
}
@@ -283,7 +284,7 @@ function file_ajax_upload() {
$form['#prefix'] .= theme('status_messages');
$output = drupal_render($form);
$js = drupal_add_js();
$settings = call_user_func_array('array_merge_recursive', $js['settings']['data']);
$settings = drupal_array_merge_deep_array($js['settings']['data']);
$commands[] = ajax_command_replace(NULL, $output, $settings);
return array('#type' => 'ajax', '#commands' => $commands);
@@ -1066,11 +1067,18 @@ function file_icon_map($file) {
* @param $field_type
* (optional) The name of a field type. If given, limits the reference check
* to fields of the given type.
* @param $check_access
* (optional) A boolean that specifies whether the permissions of the current
* user should be checked when retrieving references. If FALSE, all
* references to the file are returned. If TRUE, only references from
* entities that the current user has access to are returned. Defaults to
* TRUE for backwards compatibility reasons, but FALSE is recommended for
* most situations.
*
* @return
* An integer value.
*/
function file_get_file_references($file, $field = NULL, $age = FIELD_LOAD_REVISION, $field_type = 'file') {
function file_get_file_references($file, $field = NULL, $age = FIELD_LOAD_REVISION, $field_type = 'file', $check_access = TRUE) {
$references = drupal_static(__FUNCTION__, array());
$fields = isset($field) ? array($field['field_name'] => $field) : field_info_fields();
@@ -1081,6 +1089,11 @@ function file_get_file_references($file, $field = NULL, $age = FIELD_LOAD_REVISI
$query
->fieldCondition($file_field, 'fid', $file->fid)
->age($age);
if (!$check_access) {
// Neutralize the 'entity_field_access' query tag added by
// field_sql_storage_field_storage_query().
$query->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT');
}
$references[$field_name] = $query->execute();
}
}
+147
View File
@@ -1551,6 +1551,153 @@ class FilePrivateTestCase extends FileFieldTestCase {
$this->assertNoRaw($node_file->filename, 'File without view field access permission does not appear after attempting to attach it to a new node.');
$this->drupalGet(file_create_url($node_file->uri));
$this->assertResponse(403, 'Confirmed that access is denied for the file without view field access permission after attempting to attach it to a new node.');
// As an anonymous user, create a temporary file with no references and
// confirm that only the session that uploaded it may view it.
$this->drupalLogout();
user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array(
"create $type_name content",
'access content',
));
$test_file = $this->getTestFile('text');
$this->drupalGet('node/add/' . $type_name);
$edit = array('files[' . $field_name . '_' . LANGUAGE_NONE . '_0]' => drupal_realpath($test_file->uri));
$this->drupalPost(NULL, $edit, t('Upload'));
$files = file_load_multiple(array(), array('uid' => 0));
$this->assertEqual(1, count($files), 'Loaded one anonymous file.');
$file = end($files);
$this->assertNotEqual($file->status, FILE_STATUS_PERMANENT, 'File is temporary.');
$usage = file_usage_list($file);
$this->assertFalse($usage, 'No file usage found.');
$file_url = file_create_url($file->uri);
$this->drupalGet($file_url);
$this->assertResponse(200, 'Confirmed that the anonymous uploader has access to the temporary file.');
// Close the prior connection and remove the session cookie.
$this->curlClose();
$this->cookies = array();
$this->drupalGet($file_url);
$this->assertResponse(403, 'Confirmed that another anonymous user cannot access the temporary file.');
// As an anonymous user, create a permanent file that is referenced by a
// published node and confirm that all anonymous users may view it.
$test_file = $this->getTestFile('text');
$this->drupalGet('node/add/' . $type_name);
$edit = array();
$edit['title'] = $this->randomName();
$edit['files[' . $field_name . '_' . LANGUAGE_NONE . '_0]'] = drupal_realpath($test_file->uri);
$this->drupalPost(NULL, $edit, t('Save'));
$new_node = $this->drupalGetNodeByTitle($edit['title']);
$file = file_load($new_node->{$field_name}[LANGUAGE_NONE][0]['fid']);
$this->assertEqual($file->status, FILE_STATUS_PERMANENT, 'File is permanent.');
$usage = file_usage_list($file);
$this->assertTrue($usage, 'File usage found.');
$file_url = file_create_url($file->uri);
$this->drupalGet($file_url);
$this->assertResponse(200, 'Confirmed that the anonymous uploader has access to the permanent file that is referenced by a published node.');
// Close the prior connection and remove the session cookie.
$this->curlClose();
$this->cookies = array();
$this->drupalGet($file_url);
$this->assertResponse(200, 'Confirmed that another anonymous user also has access to the permanent file that is referenced by a published node.');
// As an anonymous user, create a permanent file that is referenced by an
// unpublished node and confirm that no anonymous users may view it (even
// the session that uploaded the file) because they cannot view the
// unpublished node.
$test_file = $this->getTestFile('text');
$this->drupalGet('node/add/' . $type_name);
$edit = array();
$edit['title'] = $this->randomName();
$edit['files[' . $field_name . '_' . LANGUAGE_NONE . '_0]'] = drupal_realpath($test_file->uri);
$this->drupalPost(NULL, $edit, t('Save'));
$new_node = $this->drupalGetNodeByTitle($edit['title']);
$new_node->status = NODE_NOT_PUBLISHED;
node_save($new_node);
$file = file_load($new_node->{$field_name}[LANGUAGE_NONE][0]['fid']);
$this->assertEqual($file->status, FILE_STATUS_PERMANENT, 'File is permanent.');
$usage = file_usage_list($file);
$this->assertTrue($usage, 'File usage found.');
$file_url = file_create_url($file->uri);
$this->drupalGet($file_url);
$this->assertResponse(403, 'Confirmed that the anonymous uploader cannot access the permanent file when it is referenced by an unpublished node.');
// Close the prior connection and remove the session cookie.
$this->curlClose();
$this->cookies = array();
$this->drupalGet($file_url);
$this->assertResponse(403, 'Confirmed that another anonymous user cannot access the permanent file when it is referenced by an unpublished node.');
}
/**
* Tests file access for private nodes when file download access is granted.
*/
function testPrivateFileDownloadAccessGranted() {
// Tell file_module_test to attempt to grant access to all private files,
// and ensure that it is doing so correctly.
$test_file = $this->getTestFile('text');
$uri = file_unmanaged_move($test_file->uri, 'private://');
$file_url = file_create_url($uri);
$this->drupalGet($file_url);
$this->assertResponse(403, 'Access is not granted to an arbitrary private file by default.');
variable_set('file_module_test_grant_download_access', TRUE);
$this->drupalGet($file_url);
$this->assertResponse(200, 'Access is granted to an arbitrary private file after a module grants access to all private files in hook_file_download().');
// Create a public node with a file attached.
$type_name = 'page';
$field_name = strtolower($this->randomName());
$this->createFileField($field_name, $type_name, array('uri_scheme' => 'private'));
$test_file = $this->getTestFile('text');
$nid = $this->uploadNodeFile($test_file, $field_name, $type_name, TRUE, array('private' => FALSE));
$node = node_load($nid, NULL, TRUE);
$file_url = file_create_url($node->{$field_name}[LANGUAGE_NONE][0]['uri']);
// Unpublish the node and ensure that only administrators (not anonymous
// users) can access the node and download the file; the expectation is
// that the File module's hook_file_download() implementation will deny
// access and thereby override the file_module_test module's access grant.
$node->status = NODE_NOT_PUBLISHED;
node_save($node);
$this->drupalLogin($this->admin_user);
$this->drupalGet("node/$nid");
$this->assertResponse(200, 'Administrator can access the unpublished node.');
$this->drupalGet($file_url);
$this->assertResponse(200, 'Administrator can download the file attached to the unpublished node.');
$this->drupalLogOut();
$this->drupalGet("node/$nid");
$this->assertResponse(403, 'Anonymous user cannot access the unpublished node.');
$this->drupalGet($file_url);
$this->assertResponse(403, 'Anonymous user cannot download the file attached to the unpublished node.');
// Re-publish the node and ensure that the node and file can be accessed by
// everyone.
$node->status = NODE_PUBLISHED;
node_save($node);
$this->drupalLogin($this->admin_user);
$this->drupalGet("node/$nid");
$this->assertResponse(200, 'Administrator can access the published node.');
$this->drupalGet($file_url);
$this->assertResponse(200, 'Administrator can download the file attached to the published node.');
$this->drupalLogOut();
$this->drupalGet("node/$nid");
$this->assertResponse(200, 'Anonymous user can access the published node.');
$this->drupalGet($file_url);
$this->assertResponse(200, 'Anonymous user can download the file attached to the published node.');
// Make the node private via the node access system and test that only
// administrators (not anonymous users) can access the node and download
// the file.
$node->private = TRUE;
node_save($node);
$this->drupalLogin($this->admin_user);
$this->drupalGet("node/$nid");
$this->assertResponse(200, 'Administrator can access the private node.');
$this->drupalGet($file_url);
$this->assertResponse(200, 'Administrator can download the file attached to the private node.');
$this->drupalLogOut();
$this->drupalGet("node/$nid");
$this->assertResponse(403, 'Anonymous user cannot access the private node.');
$this->drupalGet($file_url);
$this->assertResponse(403, 'Anonymous user cannot download the file attached to the private node.');
}
}
+3 -3
View File
@@ -5,8 +5,8 @@ version = VERSION
core = 7.x
hidden = TRUE
; Information added by Drupal.org packaging script on 2017-02-01
version = "7.54"
; Information added by Drupal.org packaging script on 2018-03-28
version = "7.58"
project = "drupal"
datestamp = "1485986921"
datestamp = "1522264019"
@@ -67,3 +67,18 @@ function file_module_test_form_submit($form, &$form_state) {
}
drupal_set_message(t('The file id is %fid.', array('%fid' => $fid)));
}
/**
* Implements hook_file_download().
*/
function file_module_test_file_download($uri) {
if (variable_get('file_module_test_grant_download_access')) {
// Mimic what file_get_content_headers() would do if we had a full $file
// object to pass to it.
return array(
'Content-Type' => mime_header_encode(file_get_mimetype($uri)),
'Content-Length' => filesize($uri),
'Cache-Control' => 'private',
);
}
}