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}
* @readonly
*/
var entityMap = {
const entityMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&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
*
@ -472,6 +461,17 @@ jQuery.PrivateBin = (function($, RawDeflate) {
return expirationDate;
};
/**
* resets state, used for unit testing
*
* @name Helper.reset
* @function
*/
me.reset = function()
{
baseUri = null;
};
return me;
})();
@ -633,7 +633,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
if (containsLinks || $element === null) {
for (let i = 0; i < args.length; ++i) {
// 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]);
}
}
@ -2423,10 +2423,13 @@ jQuery.PrivateBin = (function($, RawDeflate) {
}
// escape HTML entities, link URLs, sanitize
const escapedLinkedText = Helper.urls2links(
Helper.htmlEntities(text).split('&#x2F;').join('/')
),
sanitizedLinkedText = DOMPurify.sanitize(escapedLinkedText);
const escapedLinkedText = Helper.urls2links(text),
sanitizedLinkedText = DOMPurify.sanitize(
escapedLinkedText, {
ALLOWED_TAGS: ['a'],
ALLOWED_ATTR: ['href', 'rel']
}
);
$plainText.html(sanitizedLinkedText);
$prettyPrint.html(sanitizedLinkedText);
@ -3240,7 +3243,10 @@ jQuery.PrivateBin = (function($, RawDeflate) {
// set & parse text
$commentEntryData.html(
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
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
$('.modal').on('show.bs.modal', function(e) {

View file

@ -93,11 +93,11 @@ describe('Helper', function () {
jsc.array(common.jscHashString()),
'string',
function (prefix, schema, address, query, fragment, postfix) {
var query = query.join(''),
fragment = fragment.join(''),
url = schema + '://' + address.join('') + '/?' + query + '#' + fragment,
prefix = $.PrivateBin.Helper.htmlEntities(prefix),
postfix = ' ' + $.PrivateBin.Helper.htmlEntities(postfix);
query = query.join('');
fragment = fragment.join('');
prefix = $.PrivateBin.Helper.htmlEntities(prefix);
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
if (
@ -118,9 +118,9 @@ describe('Helper', function () {
jsc.array(common.jscQueryString()),
'string',
function (prefix, query, postfix) {
var url = 'magnet:?' + query.join('').replace(/^&+|&+$/gm,''),
prefix = $.PrivateBin.Helper.htmlEntities(prefix),
postfix = $.PrivateBin.Helper.htmlEntities(postfix);
prefix = $.PrivateBin.Helper.htmlEntities(prefix);
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);
}
);

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/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="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" />

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/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="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" />