summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Rothstein <drothstein@gmail.com>2013-01-16 16:45:48 -0500
committerDavid Rothstein <drothstein@gmail.com>2013-01-16 16:45:48 -0500
commit1d4604da252f0e6e19339957ec214388f61b908d (patch)
tree70f9fcda3737207074200a44e7cf949aebc60c66
parentb47f95d3013619e33cafdf8b769b2b6179a07956 (diff)
downloadbrdo-1d4604da252f0e6e19339957ec214388f61b908d.tar.gz
brdo-1d4604da252f0e6e19339957ec214388f61b908d.tar.bz2
Drupal 7.19
-rw-r--r--CHANGELOG.txt4
-rw-r--r--includes/bootstrap.inc2
-rw-r--r--misc/collapse.js4
-rw-r--r--misc/drupal.js21
-rw-r--r--misc/vertical-tabs.js4
-rw-r--r--modules/book/book.pages.inc9
-rw-r--r--modules/book/book.test7
-rw-r--r--modules/image/image.module3
8 files changed, 48 insertions, 6 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 7f4f0ffe1..08acf95a7 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,3 +1,7 @@
+Drupal 7.19, 2013-01-16
+-----------------------
+- Fixed security issues (multiple vulnerabilities). See SA-CORE-2013-001.
+
Drupal 7.18, 2012-12-19
-----------------------
- Fixed security issues (multiple vulnerabilities). See SA-CORE-2012-004.
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 1b48217bc..53f70e1a3 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -8,7 +8,7 @@
/**
* The current system version.
*/
-define('VERSION', '7.18');
+define('VERSION', '7.19');
/**
* Core API compatibility.
diff --git a/misc/collapse.js b/misc/collapse.js
index bd51ce532..512ff2f9f 100644
--- a/misc/collapse.js
+++ b/misc/collapse.js
@@ -58,9 +58,9 @@ Drupal.behaviors.collapse = {
$('fieldset.collapsible', context).once('collapse', function () {
var $fieldset = $(this);
// Expand fieldset if there are errors inside, or if it contains an
- // element that is targeted by the URI fragment identifier.
+ // element that is targeted by the URI fragment identifier.
var anchor = location.hash && location.hash != '#' ? ', ' + location.hash : '';
- if ($('.error' + anchor, $fieldset).length) {
+ if ($fieldset.find('.error' + anchor).length) {
$fieldset.removeClass('collapsed');
}
diff --git a/misc/drupal.js b/misc/drupal.js
index 83b088428..643baa1bf 100644
--- a/misc/drupal.js
+++ b/misc/drupal.js
@@ -7,6 +7,27 @@ jQuery.noConflict();
(function ($) {
/**
+ * Override jQuery.fn.init to guard against XSS attacks.
+ *
+ * See http://bugs.jquery.com/ticket/9521
+ */
+var jquery_init = $.fn.init;
+$.fn.init = function (selector, context, rootjQuery) {
+ // If the string contains a "#" before a "<", treat it as invalid HTML.
+ if (selector && typeof selector === 'string') {
+ var hash_position = selector.indexOf('#');
+ if (hash_position >= 0) {
+ var bracket_position = selector.indexOf('<');
+ if (bracket_position > hash_position) {
+ throw 'Syntax error, unrecognized expression: ' + selector;
+ }
+ }
+ }
+ return jquery_init.call(this, selector, context, rootjQuery);
+};
+$.fn.init.prototype = jquery_init.prototype;
+
+/**
* Attach all registered behaviors to a page element.
*
* Behaviors are event-triggered actions that attach to page elements, enhancing
diff --git a/misc/vertical-tabs.js b/misc/vertical-tabs.js
index 14d06607b..ebfaa4f7f 100644
--- a/misc/vertical-tabs.js
+++ b/misc/vertical-tabs.js
@@ -50,8 +50,8 @@ Drupal.behaviors.verticalTabs = {
if (!tab_focus) {
// If the current URL has a fragment and one of the tabs contains an
// element that matches the URL fragment, activate that tab.
- if (window.location.hash && $(window.location.hash, this).length) {
- tab_focus = $(window.location.hash, this).closest('.vertical-tabs-pane');
+ if (window.location.hash && $(this).find(window.location.hash).length) {
+ tab_focus = $(this).find(window.location.hash).closest('.vertical-tabs-pane');
}
else {
tab_focus = $('> .vertical-tabs-pane:first', this);
diff --git a/modules/book/book.pages.inc b/modules/book/book.pages.inc
index 583eb7a81..63a1d15a4 100644
--- a/modules/book/book.pages.inc
+++ b/modules/book/book.pages.inc
@@ -38,6 +38,15 @@ function book_render() {
* format determined by the $type parameter.
*/
function book_export($type, $nid) {
+ // Check that the node exists and that the current user has access to it.
+ $node = node_load($nid);
+ if (!$node) {
+ return MENU_NOT_FOUND;
+ }
+ if (!node_access('view', $node)) {
+ return MENU_ACCESS_DENIED;
+ }
+
$type = drupal_strtolower($type);
$export_function = 'book_export_' . $type;
diff --git a/modules/book/book.test b/modules/book/book.test
index d1f527387..2708e3674 100644
--- a/modules/book/book.test
+++ b/modules/book/book.test
@@ -258,6 +258,13 @@ class BookTestCase extends DrupalWebTestCase {
// Try getting the URL directly, and verify it fails.
$this->drupalGet('book/export/html/' . $this->book->nid);
$this->assertResponse('403', t('Anonymous user properly forbidden.'));
+
+ // Now grant anonymous users permission to view the printer-friendly
+ // version and verify that node access restrictions still prevent them from
+ // seeing it.
+ user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access printer-friendly version'));
+ $this->drupalGet('book/export/html/' . $this->book->nid);
+ $this->assertResponse('403', 'Anonymous user properly forbidden from seeing the printer-friendly version when denied by node access.');
}
/**
diff --git a/modules/image/image.module b/modules/image/image.module
index ff50452d5..07f489233 100644
--- a/modules/image/image.module
+++ b/modules/image/image.module
@@ -292,7 +292,8 @@ function image_file_download($uri) {
if ($info = image_get_info($uri)) {
// Check the permissions of the original to grant access to this image.
$headers = module_invoke_all('file_download', $original_uri);
- if (!in_array(-1, $headers)) {
+ // Confirm there's at least one module granting access and none denying access.
+ if (!empty($headers) && !in_array(-1, $headers)) {
return array(
// Send headers describing the image's size, and MIME-type...
'Content-Type' => $info['mime_type'],