debian-mirror-gitlab/app/assets/javascripts/lib/dompurify.js

59 lines
1.8 KiB
JavaScript
Raw Normal View History

2021-01-03 14:25:43 +05:30
import { sanitize as dompurifySanitize, addHook } from 'dompurify';
2021-10-29 20:43:33 +05:30
import { getNormalizedURL, getBaseURL, relativePathToAbsolute } from '~/lib/utils/url_utility';
2021-01-03 14:25:43 +05:30
const defaultConfig = {
2021-10-27 15:23:28 +05:30
// Safely allow SVG <use> tags
2021-11-11 11:23:49 +05:30
ADD_TAGS: ['use', 'gl-emoji'],
2021-10-27 15:23:28 +05:30
// Prevent possible XSS attacks with data-* attributes used by @rails/ujs
// See https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1421
FORBID_ATTR: ['data-remote', 'data-url', 'data-type', 'data-method'],
2021-01-03 14:25:43 +05:30
};
// Only icons urls from `gon` are allowed
const getAllowedIconUrls = (gon = window.gon) =>
2021-10-29 20:43:33 +05:30
[gon.sprite_file_icons, gon.sprite_icons]
.filter(Boolean)
.map((path) => relativePathToAbsolute(path, getBaseURL()));
2021-01-03 14:25:43 +05:30
2021-10-29 20:43:33 +05:30
const isUrlAllowed = (url) =>
getAllowedIconUrls().some((allowedUrl) => getNormalizedURL(url).startsWith(allowedUrl));
2021-01-03 14:25:43 +05:30
2021-10-29 20:43:33 +05:30
const isHrefSafe = (url) => url.match(/^#/) || isUrlAllowed(url);
2021-01-03 14:25:43 +05:30
const removeUnsafeHref = (node, attr) => {
if (!node.hasAttribute(attr)) {
return;
}
if (!isHrefSafe(node.getAttribute(attr))) {
node.removeAttribute(attr);
}
};
/**
* Sanitize icons' <use> tag attributes, to safely include
* svgs such as in:
*
* <svg viewBox="0 0 100 100">
* <use href="/assets/icons-xxx.svg#icon_name"></use>
* </svg>
*
2021-10-29 20:43:33 +05:30
* It validates both href & xlink:href attributes.
* Note that `xlink:href` is deprecated, but still in use
* https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
*
2021-01-03 14:25:43 +05:30
* @param {Object} node - Node to sanitize
*/
2021-03-08 18:12:59 +05:30
const sanitizeSvgIcon = (node) => {
2021-01-03 14:25:43 +05:30
removeUnsafeHref(node, 'href');
removeUnsafeHref(node, 'xlink:href');
};
2021-03-08 18:12:59 +05:30
addHook('afterSanitizeAttributes', (node) => {
2021-01-03 14:25:43 +05:30
if (node.tagName.toLowerCase() === 'use') {
sanitizeSvgIcon(node);
}
});
2021-11-11 11:23:49 +05:30
export const sanitize = (val, config) => dompurifySanitize(val, { ...defaultConfig, ...config });