Ver Fonte

introducing CSP header to mitigate XSS attacks, closes #10

El RIDO há 10 anos atrás
pai
commit
addb666a23

+ 2 - 1
CHANGELOG.md

@@ -8,11 +8,12 @@
     * ADDED: Option to disable vizhashs in discussions (will only affect newly created pastes)
     * ADDED: Composer support
     * CHANGED: Renamed the ZeroBin fork to PrivateBin
-    * CHANGED: Removed unmaintained RainTPL template engine, replacing the templates with straight forward PHP file
+    * CHANGED: Removed unmaintained RainTPL template engine, replacing the templates with straight forward PHP files
     * CHANGED: New favicon
     * CHANGED: Upgrading SJCL library to 1.0.4
     * CHANGED: Switched to GCM instead CCM mode for AES encryption for newly created pastes
     * CHANGED: Switched to a SHA256 HMAC of the IP in traffic limiter instead of storing it in plain text on the server
+    * CHANGED: Introduced content security policy header to reduce cross site scripting (XSS) risks
     * CHANGED: Refactored PHP code to conform to PSR-4 and PSR-2 standards.
     * FIXED: Content-type negociation for HTML in certain uncommon browser configurations
     * FIXED: JavaScript error displayed before page is loaded or during attachment load

+ 7 - 0
cfg/conf.ini.sample

@@ -59,6 +59,13 @@ languageselection = false
 ; and a rainbow table is generated for all IPs. Enabled by default.
 ; vizhash = false
 
+; Content Security Policy headers allow a website to restrict what sources are
+; allowed to be accessed in its context. You need to change this if you added
+; custom scripts from third-party domains to your templates, e.g. tracking
+; scripts or run your site behind certain DDoS-protection services.
+; Check the documentation at https://content-security-policy.com/
+cspheader = "default-src 'none'; connect-src *; script-src 'self'; style-src 'self'; font-src 'self'; img-src 'self';"
+
 ; stay compatible with PrivateBin Alpha 0.19, less secure
 ; if enabled will use base64.js version 1.7 instead of 2.1.9 and sha1 instead of
 ; sha256 in HMAC for the deletion token

+ 48 - 1
js/privatebin.js

@@ -281,7 +281,7 @@ $(function() {
         getCookie: function(cname) {
             var name = cname + '=';
             var ca = document.cookie.split(';');
-            for(var i = 0; i < ca.length; ++i) {
+            for (var i = 0; i < ca.length; ++i) {
                 var c = ca[i];
                 while (c.charAt(0) === ' ') c = c.substring(1);
                 if (c.indexOf(name) === 0)
@@ -1249,6 +1249,45 @@ $(function() {
             $('.navbar-toggle').click();
         },
 
+        /**
+         * Set the expiration on bootstrap templates.
+         *
+         * @param Event event
+         */
+        setExpiration: function(event)
+        {
+            event.preventDefault();
+            var target = $(event.target);
+            $('#pasteExpiration').val(target.data('expiration'));
+            $('#pasteExpirationDisplay').text(target.text());
+        },
+
+        /**
+         * Set the format on bootstrap templates.
+         *
+         * @param Event event
+         */
+        setFormat: function(event)
+        {
+            event.preventDefault();
+            var target = $(event.target);
+            $('#pasteFormatter').val(target.data('format'));
+            $('#pasteFormatterDisplay').text(target.text());
+        },
+
+        /**
+         * Set the language on bootstrap templates.
+         *
+         * Sets the language cookie and reloads the page.
+         *
+         * @param Event event
+         */
+        setLanguage: function(event)
+        {
+            document.cookie = 'lang=' + $(event.target).data('lang');
+            this.reloadPage(event);
+        },
+
         /**
          * Support input of tab character.
          *
@@ -1388,6 +1427,14 @@ $(function() {
             this.message.keydown(this.supportTabs);
             this.messageEdit.click($.proxy(this.viewEditor, this));
             this.messagePreview.click($.proxy(this.viewPreview, this));
+
+            // bootstrap template drop downs
+            $('ul.dropdown-menu li a', $('#expiration').parent()).click($.proxy(this.setExpiration, this));
+            $('ul.dropdown-menu li a', $('#formatter').parent()).click($.proxy(this.setFormat, this));
+            $('#language ul.dropdown-menu li a').click($.proxy(this.setLanguage, this));
+
+            // page template drop down
+            $('#language select option').click($.proxy(this.setLanguage, this));
         },
 
         /**

+ 1 - 0
lib/Configuration.php

@@ -51,6 +51,7 @@ class Configuration
             'languagedefault' => '',
             'urlshortener' => '',
             'vizhash' => true,
+            'cspheader' => 'default-src \'none\'; connect-src *; script-src \'self\'; style-src \'self\'; font-src \'self\'; img-src \'self\';',
             'zerobincompatibility' => false,
         ),
         'expire' => array(

+ 1 - 0
lib/PrivateBin.php

@@ -402,6 +402,7 @@ class PrivateBin
         header('Expires: ' . $time);
         header('Last-Modified: ' . $time);
         header('Vary: Accept');
+        header('Content-Security-Policy: ' . $this->_conf->getKey('cspheader'));
 
         // label all the expiration options
         $expire = array();

+ 3 - 3
tpl/bootstrap-compact.php

@@ -107,7 +107,7 @@ endforeach;
 foreach ($EXPIRE as $key => $value):
 ?>
 								<li>
-									<a href="#" onclick="$('#pasteExpiration').val('<?php echo $key; ?>');$('#pasteExpirationDisplay').text('<?php echo $value; ?>');return false;">
+									<a href="#" data-expiration="<?php echo $key; ?>">
 										<?php echo $value; ?>
 									</a>
 								</li>
@@ -155,7 +155,7 @@ endif;
 foreach ($FORMATTER as $key => $value):
 ?>
 								<li>
-									<a href="#" onclick="$('#pasteFormatter').val('<?php echo $key; ?>');$('#pasteFormatterDisplay').text('<?php echo $value; ?>');return false;">
+									<a href="#" data-format="<?php echo $key; ?>">
 										<?php echo $value; ?>
 									</a>
 								</li>
@@ -219,7 +219,7 @@ if (strlen($LANGUAGESELECTION)):
     foreach ($LANGUAGES as $key => $value):
 ?>
 								<li>
-									<a href="#" class="reloadlink" onclick="document.cookie='lang={$key}';">
+									<a href="#" data-lang="<?php echo $key; ?>">
 										<?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
 									</a>
 								</li>

+ 3 - 3
tpl/bootstrap-dark-page.php

@@ -106,7 +106,7 @@ endforeach;
 foreach ($EXPIRE as $key => $value):
 ?>
 							<li>
-								<a href="#" onclick="$('#pasteExpiration').val('<?php echo $key; ?>');$('#pasteExpirationDisplay').text('<?php echo $value; ?>');return false;">
+								<a href="#" data-expiration="<?php echo $key; ?>">
 									<?php echo $value; ?>
 								</a>
 							</li>
@@ -193,7 +193,7 @@ endforeach;
 foreach ($FORMATTER as $key => $value):
 ?>
 							<li>
-								<a href="#" onclick="$('#pasteFormatter').val('<?php echo $key; ?>');$('#pasteFormatterDisplay').text('<?php echo $value; ?>');return false;">
+								<a href="#" data-format="<?php echo $key; ?>">
 									<?php echo $value; ?>
 								</a>
 							</li>
@@ -214,7 +214,7 @@ if (strlen($LANGUAGESELECTION)):
     foreach ($LANGUAGES as $key => $value):
 ?>
 							<li>
-								<a href="#" class="reloadlink" onclick="document.cookie='lang=<?php echo $key; ?>';">
+								<a href="#" data-lang="<?php echo $key; ?>">
 									<?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
 								</a>
 							</li>

+ 3 - 3
tpl/bootstrap-dark.php

@@ -106,7 +106,7 @@ endforeach;
 foreach ($EXPIRE as $key => $value):
 ?>
 							<li>
-								<a href="#" onclick="$('#pasteExpiration').val('<?php echo $key; ?>');$('#pasteExpirationDisplay').text('<?php echo $value; ?>');return false;">
+								<a href="#" data-expiration="<?php echo $key; ?>">
 									<?php echo $value; ?>
 								</a>
 							</li>
@@ -193,7 +193,7 @@ endforeach;
 foreach ($FORMATTER as $key => $value):
 ?>
 							<li>
-								<a href="#" onclick="$('#pasteFormatter').val('<?php echo $key; ?>');$('#pasteFormatterDisplay').text('<?php echo $value; ?>');return false;">
+								<a href="#" data-format="<?php echo $key; ?>">
 									<?php echo $value; ?>
 								</a>
 							</li>
@@ -214,7 +214,7 @@ if (strlen($LANGUAGESELECTION)):
     foreach ($LANGUAGES as $key => $value):
 ?>
 							<li>
-								<a href="#" class="reloadlink" onclick="document.cookie='lang=<?php echo $key; ?>';">
+								<a href="#" data-lang="<?php echo $key; ?>">
 									<?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
 								</a>
 							</li>

+ 3 - 3
tpl/bootstrap-page.php

@@ -106,7 +106,7 @@ endforeach;
 foreach ($EXPIRE as $key => $value):
 ?>
 							<li>
-								<a href="#" onclick="$('#pasteExpiration').val('<?php echo $key; ?>');$('#pasteExpirationDisplay').text('<?php echo $value; ?>');return false;">
+								<a href="#" data-expiration="<?php echo $key; ?>">
 									<?php echo $value; ?>
 								</a>
 							</li>
@@ -193,7 +193,7 @@ endforeach;
 foreach ($FORMATTER as $key => $value):
 ?>
 							<li>
-								<a href="#" onclick="$('#pasteFormatter').val('<?php echo $key; ?>');$('#pasteFormatterDisplay').text('<?php echo $value; ?>');return false;">
+								<a href="#" data-format="<?php echo $key; ?>">
 									<?php echo $value; ?>
 								</a>
 							</li>
@@ -214,7 +214,7 @@ if (strlen($LANGUAGESELECTION)):
     foreach ($LANGUAGES as $key => $value):
 ?>
 							<li>
-								<a href="#" class="reloadlink" onclick="document.cookie='lang=<?php echo $key; ?>';">
+								<a href="#" data-lang="<?php echo $key; ?>">
 									<?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
 								</a>
 							</li>

+ 3 - 3
tpl/bootstrap.php

@@ -106,7 +106,7 @@ endforeach;
 foreach ($EXPIRE as $key => $value):
 ?>
 							<li>
-								<a href="#" onclick="$('#pasteExpiration').val('<?php echo $key; ?>');$('#pasteExpirationDisplay').text('<?php echo $value; ?>');return false;">
+								<a href="#" data-expiration="<?php echo $key; ?>">
 									<?php echo $value; ?>
 								</a>
 							</li>
@@ -193,7 +193,7 @@ endforeach;
 foreach ($FORMATTER as $key => $value):
 ?>
 							<li>
-								<a href="#" onclick="$('#pasteFormatter').val('<?php echo $key; ?>');$('#pasteFormatterDisplay').text('<?php echo $value; ?>');return false;">
+								<a href="#" data-format="<?php echo $key; ?>">
 									<?php echo $value; ?>
 								</a>
 							</li>
@@ -214,7 +214,7 @@ if (strlen($LANGUAGESELECTION)):
     foreach ($LANGUAGES as $key => $value):
 ?>
 							<li>
-								<a href="#" class="reloadlink" onclick="document.cookie='lang=<?php echo $key; ?>';">
+								<a href="#" data-lang="<?php echo $key; ?>">
 									<?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
 								</a>
 							</li>

+ 1 - 1
tpl/page.php

@@ -159,7 +159,7 @@ if (strlen($LANGUAGESELECTION)):
 <?php
     foreach ($LANGUAGES as $key => $value):
 ?>
-							<option class="reloadlink" onclick="document.cookie='lang=<?php echo $key; ?>';" value="<?php echo $key; ?>"<?php
+							<option data-lang="<?php echo $key; ?>" value="<?php echo $key; ?>"<?php
         if ($key == $LANGUAGESELECTION):
 ?> selected="selected"<?php
         endif;