in translation, allow links to be inserted unencoded into href attribute, simplfy sanitation by allowing only <a> tags in DOMpurify for plain text and comments and avoid DOMpurify removing magnet links, fixes #579

This commit is contained in:
El RIDO 2020-02-02 07:08:38 +01:00
parent 3996f82404
commit 2cbb8bf3ca
No known key found for this signature in database
GPG Key ID: 0F5C940A6BD81F92
4 changed files with 38 additions and 29 deletions

View File

@ -198,7 +198,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
* @enum {Object} * @enum {Object}
* @readonly * @readonly
*/ */
var entityMap = { const entityMap = {
'&': '&amp;', '&': '&amp;',
'<': '&lt;', '<': '&lt;',
'>': '&gt;', '>': '&gt;',
@ -422,17 +422,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
); );
} }
/**
* resets state, used for unit testing
*
* @name Helper.reset
* @function
*/
me.reset = function()
{
baseUri = null;
};
/** /**
* calculate expiration date given initial date and expiration period * calculate expiration date given initial date and expiration period
* *
@ -472,6 +461,17 @@ jQuery.PrivateBin = (function($, RawDeflate) {
return expirationDate; return expirationDate;
}; };
/**
* resets state, used for unit testing
*
* @name Helper.reset
* @function
*/
me.reset = function()
{
baseUri = null;
};
return me; return me;
})(); })();
@ -633,7 +633,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
if (containsLinks || $element === null) { if (containsLinks || $element === null) {
for (let i = 0; i < args.length; ++i) { for (let i = 0; i < args.length; ++i) {
// parameters (i > 0) may never contain HTML as they may come from untrusted parties // parameters (i > 0) may never contain HTML as they may come from untrusted parties
if (i > 0 || !containsLinks) { if ((containsLinks ? i > 1 : i > 0) || !containsLinks) {
args[i] = Helper.htmlEntities(args[i]); args[i] = Helper.htmlEntities(args[i]);
} }
} }
@ -2423,10 +2423,13 @@ jQuery.PrivateBin = (function($, RawDeflate) {
} }
// escape HTML entities, link URLs, sanitize // escape HTML entities, link URLs, sanitize
const escapedLinkedText = Helper.urls2links( const escapedLinkedText = Helper.urls2links(text),
Helper.htmlEntities(text).split('&#x2F;').join('/') sanitizedLinkedText = DOMPurify.sanitize(
), escapedLinkedText, {
sanitizedLinkedText = DOMPurify.sanitize(escapedLinkedText); ALLOWED_TAGS: ['a'],
ALLOWED_ATTR: ['href', 'rel']
}
);
$plainText.html(sanitizedLinkedText); $plainText.html(sanitizedLinkedText);
$prettyPrint.html(sanitizedLinkedText); $prettyPrint.html(sanitizedLinkedText);
@ -3240,7 +3243,10 @@ jQuery.PrivateBin = (function($, RawDeflate) {
// set & parse text // set & parse text
$commentEntryData.html( $commentEntryData.html(
DOMPurify.sanitize( DOMPurify.sanitize(
Helper.urls2links(commentText) Helper.urls2links(commentText), {
ALLOWED_TAGS: ['a'],
ALLOWED_ATTR: ['href', 'rel']
}
) )
); );
@ -5217,7 +5223,10 @@ jQuery.PrivateBin = (function($, RawDeflate) {
// first load translations // first load translations
I18n.loadTranslations(); I18n.loadTranslations();
DOMPurify.setConfig({SAFE_FOR_JQUERY: true}); DOMPurify.setConfig({
ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|magnet):)/i,
SAFE_FOR_JQUERY: true
});
// center all modals // center all modals
$('.modal').on('show.bs.modal', function(e) { $('.modal').on('show.bs.modal', function(e) {

View File

@ -93,11 +93,11 @@ describe('Helper', function () {
jsc.array(common.jscHashString()), jsc.array(common.jscHashString()),
'string', 'string',
function (prefix, schema, address, query, fragment, postfix) { function (prefix, schema, address, query, fragment, postfix) {
var query = query.join(''), query = query.join('');
fragment = fragment.join(''), fragment = fragment.join('');
url = schema + '://' + address.join('') + '/?' + query + '#' + fragment, prefix = $.PrivateBin.Helper.htmlEntities(prefix);
prefix = $.PrivateBin.Helper.htmlEntities(prefix), postfix = ' ' + $.PrivateBin.Helper.htmlEntities(postfix);
postfix = ' ' + $.PrivateBin.Helper.htmlEntities(postfix); let url = schema + '://' + address.join('') + '/?' + query + '#' + fragment;
// special cases: When the query string and fragment imply the beginning of an HTML entity, eg. &#0 or &#x // special cases: When the query string and fragment imply the beginning of an HTML entity, eg. &#0 or &#x
if ( if (
@ -118,9 +118,9 @@ describe('Helper', function () {
jsc.array(common.jscQueryString()), jsc.array(common.jscQueryString()),
'string', 'string',
function (prefix, query, postfix) { function (prefix, query, postfix) {
var url = 'magnet:?' + query.join('').replace(/^&+|&+$/gm,''), prefix = $.PrivateBin.Helper.htmlEntities(prefix);
prefix = $.PrivateBin.Helper.htmlEntities(prefix), postfix = $.PrivateBin.Helper.htmlEntities(postfix);
postfix = $.PrivateBin.Helper.htmlEntities(postfix); let url = 'magnet:?' + query.join('').replace(/^&+|&+$/gm,'');
return prefix + '<a href="' + url + '" rel="nofollow">' + url + '</a> ' + postfix === $.PrivateBin.Helper.urls2links(prefix + url + ' ' + postfix); return prefix + '<a href="' + url + '" rel="nofollow">' + url + '</a> ' + postfix === $.PrivateBin.Helper.urls2links(prefix + url + ' ' + postfix);
} }
); );

View File

@ -72,7 +72,7 @@ endif;
?> ?>
<script type="text/javascript" data-cfasync="false" src="js/purify-2.0.7.js" integrity="sha512-XjNEK1xwh7SJ/7FouwV4VZcGW9cMySL3SwNpXgrURLBcXXQYtZdqhGoNdEwx9vwLvFjUGDQVNgpOrTsXlSTiQg==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/purify-2.0.7.js" integrity="sha512-XjNEK1xwh7SJ/7FouwV4VZcGW9cMySL3SwNpXgrURLBcXXQYtZdqhGoNdEwx9vwLvFjUGDQVNgpOrTsXlSTiQg==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-N9tv/+S54wMKM/g9RefBwWaIvpYJ59TUWPy2LGi5jA5mt0RqkRbl4QIuaEOpUiTDynUN/KXd0zUUtB/0Ig3j5g==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-/gTtzHixkAQlU3nezV9BcElFqK1awAeK6ci1tXJJsu6Ul1CYMmiL3F307okRlXP31+X4oTE7cVWlEDegNS7RnA==" crossorigin="anonymous"></script>
<link rel="apple-touch-icon" href="img/apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" /> <link rel="apple-touch-icon" href="img/apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" />
<link rel="icon" type="image/png" href="img/favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" /> <link rel="icon" type="image/png" href="img/favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" />
<link rel="icon" type="image/png" href="img/favicon-16x16.png?<?php echo rawurlencode($VERSION); ?>" sizes="16x16" /> <link rel="icon" type="image/png" href="img/favicon-16x16.png?<?php echo rawurlencode($VERSION); ?>" sizes="16x16" />

View File

@ -50,7 +50,7 @@ endif;
?> ?>
<script type="text/javascript" data-cfasync="false" src="js/purify-2.0.7.js" integrity="sha512-XjNEK1xwh7SJ/7FouwV4VZcGW9cMySL3SwNpXgrURLBcXXQYtZdqhGoNdEwx9vwLvFjUGDQVNgpOrTsXlSTiQg==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/purify-2.0.7.js" integrity="sha512-XjNEK1xwh7SJ/7FouwV4VZcGW9cMySL3SwNpXgrURLBcXXQYtZdqhGoNdEwx9vwLvFjUGDQVNgpOrTsXlSTiQg==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-N9tv/+S54wMKM/g9RefBwWaIvpYJ59TUWPy2LGi5jA5mt0RqkRbl4QIuaEOpUiTDynUN/KXd0zUUtB/0Ig3j5g==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-/gTtzHixkAQlU3nezV9BcElFqK1awAeK6ci1tXJJsu6Ul1CYMmiL3F307okRlXP31+X4oTE7cVWlEDegNS7RnA==" crossorigin="anonymous"></script>
<link rel="apple-touch-icon" href="img/apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" /> <link rel="apple-touch-icon" href="img/apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" />
<link rel="icon" type="image/png" href="img/favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" /> <link rel="icon" type="image/png" href="img/favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" />
<link rel="icon" type="image/png" href="img/favicon-16x16.png?<?php echo rawurlencode($VERSION); ?>" sizes="16x16" /> <link rel="icon" type="image/png" href="img/favicon-16x16.png?<?php echo rawurlencode($VERSION); ?>" sizes="16x16" />