introducing CSP header to mitigate XSS attacks, closes #10

This commit is contained in:
El RIDO 2016-08-09 14:46:32 +02:00
parent a28aebae7d
commit addb666a23
11 changed files with 75 additions and 18 deletions

View File

@ -8,11 +8,12 @@
* ADDED: Option to disable vizhashs in discussions (will only affect newly created pastes) * ADDED: Option to disable vizhashs in discussions (will only affect newly created pastes)
* ADDED: Composer support * ADDED: Composer support
* CHANGED: Renamed the ZeroBin fork to PrivateBin * 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: New favicon
* CHANGED: Upgrading SJCL library to 1.0.4 * 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 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: 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. * 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: Content-type negociation for HTML in certain uncommon browser configurations
* FIXED: JavaScript error displayed before page is loaded or during attachment load * FIXED: JavaScript error displayed before page is loaded or during attachment load

View File

@ -59,6 +59,13 @@ languageselection = false
; and a rainbow table is generated for all IPs. Enabled by default. ; and a rainbow table is generated for all IPs. Enabled by default.
; vizhash = false ; 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 ; 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 ; 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 ; sha256 in HMAC for the deletion token

View File

@ -281,7 +281,7 @@ $(function() {
getCookie: function(cname) { getCookie: function(cname) {
var name = cname + '='; var name = cname + '=';
var ca = document.cookie.split(';'); 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]; var c = ca[i];
while (c.charAt(0) === ' ') c = c.substring(1); while (c.charAt(0) === ' ') c = c.substring(1);
if (c.indexOf(name) === 0) if (c.indexOf(name) === 0)
@ -1249,6 +1249,45 @@ $(function() {
$('.navbar-toggle').click(); $('.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. * Support input of tab character.
* *
@ -1388,6 +1427,14 @@ $(function() {
this.message.keydown(this.supportTabs); this.message.keydown(this.supportTabs);
this.messageEdit.click($.proxy(this.viewEditor, this)); this.messageEdit.click($.proxy(this.viewEditor, this));
this.messagePreview.click($.proxy(this.viewPreview, 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));
}, },
/** /**

View File

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

View File

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

View File

@ -107,7 +107,7 @@ endforeach;
foreach ($EXPIRE as $key => $value): foreach ($EXPIRE as $key => $value):
?> ?>
<li> <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; ?> <?php echo $value; ?>
</a> </a>
</li> </li>
@ -155,7 +155,7 @@ endif;
foreach ($FORMATTER as $key => $value): foreach ($FORMATTER as $key => $value):
?> ?>
<li> <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; ?> <?php echo $value; ?>
</a> </a>
</li> </li>
@ -219,7 +219,7 @@ if (strlen($LANGUAGESELECTION)):
foreach ($LANGUAGES as $key => $value): foreach ($LANGUAGES as $key => $value):
?> ?>
<li> <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]; ?>) <?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
</a> </a>
</li> </li>

View File

@ -106,7 +106,7 @@ endforeach;
foreach ($EXPIRE as $key => $value): foreach ($EXPIRE as $key => $value):
?> ?>
<li> <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; ?> <?php echo $value; ?>
</a> </a>
</li> </li>
@ -193,7 +193,7 @@ endforeach;
foreach ($FORMATTER as $key => $value): foreach ($FORMATTER as $key => $value):
?> ?>
<li> <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; ?> <?php echo $value; ?>
</a> </a>
</li> </li>
@ -214,7 +214,7 @@ if (strlen($LANGUAGESELECTION)):
foreach ($LANGUAGES as $key => $value): foreach ($LANGUAGES as $key => $value):
?> ?>
<li> <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]; ?>) <?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
</a> </a>
</li> </li>

View File

@ -106,7 +106,7 @@ endforeach;
foreach ($EXPIRE as $key => $value): foreach ($EXPIRE as $key => $value):
?> ?>
<li> <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; ?> <?php echo $value; ?>
</a> </a>
</li> </li>
@ -193,7 +193,7 @@ endforeach;
foreach ($FORMATTER as $key => $value): foreach ($FORMATTER as $key => $value):
?> ?>
<li> <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; ?> <?php echo $value; ?>
</a> </a>
</li> </li>
@ -214,7 +214,7 @@ if (strlen($LANGUAGESELECTION)):
foreach ($LANGUAGES as $key => $value): foreach ($LANGUAGES as $key => $value):
?> ?>
<li> <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]; ?>) <?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
</a> </a>
</li> </li>

View File

@ -106,7 +106,7 @@ endforeach;
foreach ($EXPIRE as $key => $value): foreach ($EXPIRE as $key => $value):
?> ?>
<li> <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; ?> <?php echo $value; ?>
</a> </a>
</li> </li>
@ -193,7 +193,7 @@ endforeach;
foreach ($FORMATTER as $key => $value): foreach ($FORMATTER as $key => $value):
?> ?>
<li> <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; ?> <?php echo $value; ?>
</a> </a>
</li> </li>
@ -214,7 +214,7 @@ if (strlen($LANGUAGESELECTION)):
foreach ($LANGUAGES as $key => $value): foreach ($LANGUAGES as $key => $value):
?> ?>
<li> <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]; ?>) <?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
</a> </a>
</li> </li>

View File

@ -106,7 +106,7 @@ endforeach;
foreach ($EXPIRE as $key => $value): foreach ($EXPIRE as $key => $value):
?> ?>
<li> <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; ?> <?php echo $value; ?>
</a> </a>
</li> </li>
@ -193,7 +193,7 @@ endforeach;
foreach ($FORMATTER as $key => $value): foreach ($FORMATTER as $key => $value):
?> ?>
<li> <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; ?> <?php echo $value; ?>
</a> </a>
</li> </li>
@ -214,7 +214,7 @@ if (strlen($LANGUAGESELECTION)):
foreach ($LANGUAGES as $key => $value): foreach ($LANGUAGES as $key => $value):
?> ?>
<li> <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]; ?>) <?php echo $value[0]; ?> (<?php echo $value[1]; ?>)
</a> </a>
</li> </li>

View File

@ -159,7 +159,7 @@ if (strlen($LANGUAGESELECTION)):
<?php <?php
foreach ($LANGUAGES as $key => $value): 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): if ($key == $LANGUAGESELECTION):
?> selected="selected"<?php ?> selected="selected"<?php
endif; endif;