]> git.joonet.de Git - adminer.git/commitdiff
Disallow scripts without nonce
authorJakub Vrana <jakub@vrana.cz>
Sat, 13 Jan 2018 21:17:00 +0000 (22:17 +0100)
committerJakub Vrana <jakub@vrana.cz>
Sat, 13 Jan 2018 21:19:16 +0000 (22:19 +0100)
adminer/include/adminer.inc.php
adminer/include/design.inc.php
adminer/include/functions.inc.php
adminer/include/version.inc.php
adminer/schema.inc.php
changes.txt
plugins/login-sqlite.php
plugins/tables-filter.php
plugins/tinymce.php

index aed9e0e3ad042b02833971c632bf3620faef00af..736889eb0bf5b9ad58ed507aa56a4c9136f31bf3 100644 (file)
@@ -420,7 +420,7 @@ class Adminer {
                echo "<fieldset><legend>" . lang('Action') . "</legend><div>";
                echo "<input type='submit' value='" . lang('Select') . "'>";
                echo " <span id='noindex' title='" . lang('Full table scan') . "'></span>";
-               echo "<script>\n";
+               echo "<script" . nonce() . ">\n";
                echo "var indexColumns = ";
                $columns = array();
                foreach ($indexes as $index) {
@@ -897,7 +897,7 @@ class Adminer {
                        if (support("sql")) {
                                echo script_src("../externals/jush/modules/jush-$jush.js");
                                ?>
-<script>
+<script<?php echo nonce(); ?>>
 <?php
                                if ($tables) {
                                        $links = array();
index 4fc6842c6b2d1f2468586870999e3e57f3837ea6..eea72ed01017b0e1c8e38742cbee14093217842a 100644 (file)
@@ -33,7 +33,7 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
 <?php } ?>
 
 <body class="<?php echo lang('ltr'); ?> nojs">
-<script>
+<script<?php echo nonce(); ?>>
 mixin(document.body, {onkeydown: bodyKeydown, onclick: bodyClick<?php echo (isset($_COOKIE["adminer_version"]) ? "" : ", onload: partial(verifyVersion, '$VERSION')"); ?>});
 document.body.className = document.body.className.replace(/ nojs/, ' js');
 var offlineMessage = '<?php echo js_escape(lang('You are offline.')); ?>';
@@ -109,7 +109,7 @@ function page_headers() {
 function csp() {
        return array(
                "default-src" => "'none'",
-               "script-src" => "'self' 'unsafe-inline'",
+               "script-src" => "'self' 'unsafe-inline' 'nonce-" . get_nonce() . "' 'strict-dynamic'", // 'self' is a fallback for browsers not supporting 'strict-dynamic', 'unsafe-inline' is a fallback for browsers not supporting 'nonce-'
                "style-src" => "'self' 'unsafe-inline'",
                "connect-src" => "'self'",
                "img-src" => "'self' data:",
@@ -118,6 +118,17 @@ function csp() {
        );
 }
 
+/** Get a CSP nonce
+* @return string Base64 value
+*/
+function get_nonce() {
+       static $nonce;
+       if (!$nonce) {
+               $nonce = base64_encode(rand_string());
+       }
+       return $nonce;
+}
+
 /** Print flash and error messages
 * @param string
 * @return null
index 6cfc0108b9d367855777469f2159668229967546..44722724d2aebf2bf01a784adb9b8452228e0627 100644 (file)
@@ -87,7 +87,7 @@ function charset($connection) {
 * @return string
 */
 function script($source, $trailing = "\n") {
-       return "<script>$source</script>$trailing";
+       return "<script" . nonce() . ">$source</script>$trailing";
 }
 
 /** Return <script src> element
@@ -95,7 +95,14 @@ function script($source, $trailing = "\n") {
 * @return string
 */
 function script_src($url) {
-       return "<script src='" . h($url) . "'></script>\n";
+       return "<script src='" . h($url) . "'" . nonce() . "></script>\n";
+}
+
+/** Get a nonce="" attribute with CSP nonce
+* @return string
+*/
+function nonce() {
+       return ' nonce="' . get_nonce() . '"';
 }
 
 /** Escape for HTML
@@ -1242,7 +1249,7 @@ function slow_query($query) {
        if (support("kill") && is_object($connection2 = connect()) && ($db == "" || $connection2->select_db($db))) {
                $kill = $connection2->result(connection_id()); // MySQL and MySQLi can use thread_id but it's not in PDO_MySQL
                ?>
-<script>
+<script<?php echo nonce(); ?>>
 var timeout = setTimeout(function () {
        ajax('<?php echo js_escape(ME); ?>script=kill', function () {
        }, 'token=<?php echo $token; ?>&kill=<?php echo $kill; ?>');
index 98e72eacde9d1ccf8519ae4199b3314477076f34..63110a0e7682c8c81e56aa55e14246dd693ec06e 100644 (file)
@@ -1,2 +1,2 @@
 <?php
-$VERSION = "4.3.2-dev";
+$VERSION = "4.4.0-dev";
index dfb4c402b03a5dec5c2eab97f9f054d8f4d120e3..f092d88c0b99501e2a96d86ba851b993ff0c3e69 100644 (file)
@@ -49,7 +49,7 @@ foreach (table_status('', true) as $table => $table_status) {
 
 ?>
 <div id="schema" style="height: <?php echo $top; ?>em;">
-<script>
+<script<?php echo nonce(); ?>>
 qs('#schema').onselectstart = function () { return false; };
 var tablePos = {<?php echo implode(",", $table_pos_js) . "\n"; ?>};
 var em = qs('#schema').offsetHeight / <?php echo $top; ?>;
index 093ca3299050427dfca01fa81b98090b81e0aabe..6bdd60ad923e7de256c4fb095b7a0aaa9fac5774 100644 (file)
@@ -1,5 +1,6 @@
-Adminer 4.3.2-dev:
+Adminer 4.4.0-dev:
 Add Content Security Policy
+Disallow scripts without nonce
 Add nosniff header
 PHP 7.1: Prevent warning when using empty limit
 MySQL: Remove dedicated view for replication status (added in 4.3.0)
index 1d8bf0b849af4de5b72a2fdd739702ed3522f238..2370a098fe9bfa385d20f6ef2713034c3c81c9d7 100644 (file)
@@ -14,7 +14,7 @@ class AdminerLoginSqlite {
 
        function loginForm() {
                ?>
-<script>
+<script<?php echo nonce(); ?>>
 addEventListener('load', function () {
        var driver = qs('name="auth[driver]"');
        if (isTag(driver, 'select')) {
index 773d4d9653a71a8495c8591dc19b0574c3713746..ada866b0f63950f260c3abfa1e33cea2bfa5a36c 100644 (file)
@@ -24,7 +24,7 @@ foreach ($tables as $table => $status) {
 }
 ?>
 </ul>
-<script>
+<script<?php echo nonce(); ?>>
 var tablesFilterTimeout = null;
 var tablesFilterValue = '';
 
index 59620a01a68a15bfad8d421528fd0b9d0830b28a..5190b1c8a514f68fa847825f3e64aa7f947c1d60 100644 (file)
@@ -29,7 +29,7 @@ class AdminerTinymce {
                }
                echo script_src($this->path);
                ?>
-<script>
+<script<?php echo nonce(); ?>>
 tinyMCE.init({
        mode: 'none',
        theme: 'advanced',