diff --git a/ChangeLog b/ChangeLog
index 2d9e287384..809f061ced 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,10 @@
phpMyAdmin - ChangeLog
======================
+4.0.10.3 (not yet released)
+- bug #4530 [security] DOM based XSS that results to a CSRF that creates a
+ ROOT account in certain conditions
+
4.0.10.2 (2014-08-17)
- bug #4501 [security] XSS in table browse page
- bug #4502 [security] Self-XSS in enum value editor
diff --git a/js/ajax.js b/js/ajax.js
index 77a2731aa5..1336e11fd5 100644
--- a/js/ajax.js
+++ b/js/ajax.js
@@ -714,9 +714,16 @@ AJAX.setUrlHash = (function (jQuery, window) {
if (window.location.hash.substring(0, 8) == '#PMAURL-') {
// We have a valid hash, let's redirect the user
// to the page that it's pointing to
- window.location = window.location.hash.substring(
- window.location.hash.indexOf(':') + 1
- );
+ var colon_position = window.location.hash.indexOf(':');
+ var questionmark_position = window.location.hash.indexOf('?');
+ if (colon_position != -1 && questionmark_position != -1 && colon_position < questionmark_position) {
+ var hash_url = window.location.hash.substring(colon_position + 1, questionmark_position);
+ if (PMA_gotoWhitelist.indexOf(hash_url) != -1) {
+ window.location = window.location.hash.substring(
+ colon_position + 1
+ );
+ }
+ }
} else {
// We don't have a valid hash, so we'll set it up
// when the page finishes loading
diff --git a/js/whitelist.php b/js/whitelist.php
new file mode 100644
index 0000000000..0f64f5ce32
--- /dev/null
+++ b/js/whitelist.php
@@ -0,0 +1,31 @@
+
diff --git a/libraries/Header.class.php b/libraries/Header.class.php
index f8b6a1038c..9b537c7f1d 100644
--- a/libraries/Header.class.php
+++ b/libraries/Header.class.php
@@ -146,7 +146,16 @@ class PMA_Header
*/
private function _addDefaultScripts()
{
+ // Localised strings
+ $params = array('lang' => $GLOBALS['lang']);
+ if (isset($GLOBALS['db'])) {
+ $params['db'] = $GLOBALS['db'];
+ }
+
$this->_scripts->addFile('jquery/jquery-1.8.3.min.js');
+ $this->_scripts->addFile(
+ 'whitelist.php' . PMA_generate_common_url($params), false, true
+ );
$this->_scripts->addFile('ajax.js');
$this->_scripts->addFile('keyhandler.js');
$this->_scripts->addFile('jquery/jquery-ui-1.9.2.custom.min.js');
@@ -169,11 +178,6 @@ class PMA_Header
// Here would not be a good place to add CodeMirror because
// the user preferences have not been merged at this point
- // Localised strings
- $params = array('lang' => $GLOBALS['lang']);
- if (isset($GLOBALS['db'])) {
- $params['db'] = $GLOBALS['db'];
- }
$this->_scripts->addFile('messages.php' . PMA_generate_common_url($params));
// Append the theme id to this url to invalidate
// the cache on a theme change. Though this might be
diff --git a/libraries/Scripts.class.php b/libraries/Scripts.class.php
index a3057d7e0b..a0aa73d008 100644
--- a/libraries/Scripts.class.php
+++ b/libraries/Scripts.class.php
@@ -50,6 +50,7 @@ class PMA_Scripts
*/
private function _includeFiles($files)
{
+ $first_dynamic_scripts = "";
$dynamic_scripts = "";
$params = array();
foreach ($files as $value) {
@@ -68,14 +69,18 @@ class PMA_Scripts
$params[] = "scripts[]=" . $value['filename'];
}
} else {
- $dynamic_scripts .= "";
+ if ($value['before_statics'] === true) {
+ $first_dynamic_scripts .= "";
+ } else {
+ $dynamic_scripts .= "";
+ }
}
}
$static_scripts = sprintf(
"",
implode("&", $params)
);
- return $static_scripts . $dynamic_scripts;
+ return $first_dynamic_scripts . $static_scripts . $dynamic_scripts;
}
/**
@@ -97,10 +102,12 @@ class PMA_Scripts
* @param string $filename The name of the file to include
* @param bool $conditional_ie Whether to wrap the script tag in
* conditional comments for IE
+ * @param bool $before_statics Whether this dynamic script should be
+ * include before the static ones
*
* @return void
*/
- public function addFile($filename, $conditional_ie = false)
+ public function addFile($filename, $conditional_ie = false, $before_statics = false)
{
$hash = md5($filename);
if (empty($this->_files[$hash])) {
@@ -108,7 +115,8 @@ class PMA_Scripts
$this->_files[$hash] = array(
'has_onload' => $has_onload,
'filename' => $filename,
- 'conditional_ie' => $conditional_ie
+ 'conditional_ie' => $conditional_ie,
+ 'before_statics' => $before_statics
);
}
}