Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | 1521x 1521x 1521x 89x 112x 1521x 108x 1521x 1521x 230x 119x 111x 81x 1521x 70x 70x 70x 70x 1521x 115x 115x 1521x 11231x 115x 1521x 1521x 20460x 71x 1521x 11231x 71x 71x 71x 70x 70x 5865x | import DOMPurify from 'dompurify'; import { getNormalizedURL, getBaseURL, relativePathToAbsolute } from '~/lib/utils/url_utility'; const { sanitize: dompurifySanitize, addHook, isValidAttribute } = DOMPurify; export const defaultConfig = { // Safely allow SVG <use> tags ADD_TAGS: ['use', 'gl-emoji', 'copy-code'], // 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', 'data-disable-with', 'data-disabled', 'data-disable', 'data-turbo', ], FORBID_TAGS: ['style', 'mstyle', 'form'], ALLOW_UNKNOWN_PROTOCOLS: true, }; // Only icons urls from `gon` are allowed const getAllowedIconUrls = (gon = window.gon) => [gon.sprite_file_icons, gon.sprite_icons] .filter(Boolean) .map((path) => relativePathToAbsolute(path, getBaseURL())); const isUrlAllowed = (url) => getAllowedIconUrls().some((allowedUrl) => getNormalizedURL(url).startsWith(allowedUrl)); const isHrefSafe = (url) => url.match(/^#/) || isUrlAllowed(url); const removeUnsafeHref = (node, attr) => { if (!node.hasAttribute(attr)) { return; } if (!isHrefSafe(node.getAttribute(attr))) { node.removeAttribute(attr); } }; /** * Appends 'noopener' & 'noreferrer' to rel * attr values to prevent reverse tabnabbing. * * @param {String} rel * @returns {String} */ const appendSecureRelValue = (rel) => { const attributes = new Set(rel ? rel.toLowerCase().split(' ') : []); attributes.add('noopener'); attributes.add('noreferrer'); return Array.from(attributes).join(' '); }; /** * 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> * * 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 * * @param {Object} node - Node to sanitize */ const sanitizeSvgIcon = (node) => { removeUnsafeHref(node, 'href'); removeUnsafeHref(node, 'xlink:href'); }; addHook('afterSanitizeAttributes', (node) => { if (node.tagName.toLowerCase() === 'use') { sanitizeSvgIcon(node); } }); const TEMPORARY_ATTRIBUTE = 'data-temp-href-target'; addHook('beforeSanitizeAttributes', (node) => { if (node.tagName === 'A' && node.hasAttribute('target')) { node.setAttribute(TEMPORARY_ATTRIBUTE, node.getAttribute('target')); } }); addHook('afterSanitizeAttributes', (node) => { if (node.tagName === 'A' && node.hasAttribute(TEMPORARY_ATTRIBUTE)) { node.setAttribute('target', node.getAttribute(TEMPORARY_ATTRIBUTE)); node.removeAttribute(TEMPORARY_ATTRIBUTE); if (node.getAttribute('target') === '_blank') { const rel = node.getAttribute('rel'); node.setAttribute('rel', appendSecureRelValue(rel)); } } }); export const sanitize = (val, config) => dompurifySanitize(val, { ...defaultConfig, ...config }); export { isValidAttribute }; |