diff --git a/CHANGELOG.md b/CHANGELOG.md index a1fe6fbc..8b2c0bdc 100644 --- a/CHANGELOG.md +++ b/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 diff --git a/cfg/conf.ini.sample b/cfg/conf.ini.sample index 10fd56d2..96062647 100644 --- a/cfg/conf.ini.sample +++ b/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 diff --git a/js/privatebin.js b/js/privatebin.js index 5b851389..8244c138 100644 --- a/js/privatebin.js +++ b/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)); }, /** diff --git a/lib/Configuration.php b/lib/Configuration.php index 15c35a15..44a35d63 100644 --- a/lib/Configuration.php +++ b/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( diff --git a/lib/PrivateBin.php b/lib/PrivateBin.php index e4d91e87..5985bba7 100644 --- a/lib/PrivateBin.php +++ b/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(); diff --git a/tpl/bootstrap-compact.php b/tpl/bootstrap-compact.php index 9c895bc9..95e0e864 100644 --- a/tpl/bootstrap-compact.php +++ b/tpl/bootstrap-compact.php @@ -107,7 +107,7 @@ endforeach; foreach ($EXPIRE as $key => $value): ?>