mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-09 18:39:41 +02:00
fix: sanitization bug
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { sanitizeText, removeScript, removeEscapes } from './common';
|
import { sanitizeText, removeScript } from './common';
|
||||||
|
|
||||||
describe('when securityLevel is antiscript, all script must be removed', function () {
|
describe('when securityLevel is antiscript, all script must be removed', function () {
|
||||||
/**
|
/**
|
||||||
@@ -6,7 +6,7 @@ describe('when securityLevel is antiscript, all script must be removed', functio
|
|||||||
* @param {string} result The expected sanitized text
|
* @param {string} result The expected sanitized text
|
||||||
*/
|
*/
|
||||||
function compareRemoveScript(original, result) {
|
function compareRemoveScript(original, result) {
|
||||||
expect(removeScript(original)).toEqual(result);
|
expect(removeScript(original).trim()).toEqual(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should remove all script block, script inline.', function () {
|
it('should remove all script block, script inline.', function () {
|
||||||
@@ -29,70 +29,24 @@ describe('when securityLevel is antiscript, all script must be removed', functio
|
|||||||
compareRemoveScript(
|
compareRemoveScript(
|
||||||
`This is a <a href="javascript:runHijackingScript();">clean link</a> + <a href="javascript:runHijackingScript();">clean link</a>
|
`This is a <a href="javascript:runHijackingScript();">clean link</a> + <a href="javascript:runHijackingScript();">clean link</a>
|
||||||
and <a href="javascript:bipassedMining();">me too</a>`,
|
and <a href="javascript:bipassedMining();">me too</a>`,
|
||||||
`This is a <a href="#runHijackingScript();">clean link</a> + <a href="#runHijackingScript();">clean link</a>
|
`This is a <a>clean link</a> + <a>clean link</a>
|
||||||
and <a href="#;bipassedMining();">me too</a>`
|
and <a>me too</a>`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should detect malicious images', function () {
|
it('should detect malicious images', function () {
|
||||||
compareRemoveScript(`<img onerror="alert('hello');">`, `<img onerror:"alert('hello');">`);
|
compareRemoveScript(`<img onerror="alert('hello');">`, `<img>`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should detect iframes', function () {
|
it('should detect iframes', function () {
|
||||||
compareRemoveScript(
|
compareRemoveScript(
|
||||||
`<iframe src="http://abc.com/script1.js"></iframe>
|
`<iframe src="http://abc.com/script1.js"></iframe>
|
||||||
<iframe src="http://example.com/iframeexample"></iframe>`,
|
<iframe src="http://example.com/iframeexample"></iframe>`,
|
||||||
` src="http://abc.com/script1.js"></iframe>
|
''
|
||||||
src="http://example.com/iframeexample"></iframe>`
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('remove escape code in text', function () {
|
|
||||||
it('should remove a unicode colon', function () {
|
|
||||||
const labelString = '\\u003A';
|
|
||||||
|
|
||||||
const result = removeEscapes(labelString);
|
|
||||||
expect(result).toEqual(':');
|
|
||||||
});
|
|
||||||
it('should remove a hex colon', function () {
|
|
||||||
const labelString = '\\x3A';
|
|
||||||
|
|
||||||
const result = removeEscapes(labelString);
|
|
||||||
expect(result).toEqual(':');
|
|
||||||
});
|
|
||||||
it('should remove a oct colon', function () {
|
|
||||||
const labelString = '\\72';
|
|
||||||
|
|
||||||
const result = removeEscapes(labelString);
|
|
||||||
expect(result).toEqual(':');
|
|
||||||
});
|
|
||||||
it('should remove a oct colon 3 numbers', function () {
|
|
||||||
const labelString = '\\072';
|
|
||||||
|
|
||||||
const result = removeEscapes(labelString);
|
|
||||||
expect(result).toEqual(':');
|
|
||||||
});
|
|
||||||
it('should remove multiple colons 3 numbers', function () {
|
|
||||||
const labelString = '\\072\\072\\72';
|
|
||||||
|
|
||||||
const result = removeEscapes(labelString);
|
|
||||||
expect(result).toEqual(':::');
|
|
||||||
});
|
|
||||||
it('should handle greater and smaller then', function () {
|
|
||||||
const labelString = '\\74\\076';
|
|
||||||
|
|
||||||
const result = removeEscapes(labelString);
|
|
||||||
expect(result).toEqual('<>');
|
|
||||||
});
|
|
||||||
it('should handle letters', function () {
|
|
||||||
const labelString = '\\u0073\\143ri\\x70\\u0074\\x3A';
|
|
||||||
|
|
||||||
const result = removeEscapes(labelString);
|
|
||||||
expect(result).toEqual('script:');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Sanitize text', function () {
|
describe('Sanitize text', function () {
|
||||||
it('should remove script tag', function () {
|
it('should remove script tag', function () {
|
||||||
const maliciousStr = 'javajavascript:script:alert(1)';
|
const maliciousStr = 'javajavascript:script:alert(1)';
|
||||||
|
@@ -13,22 +13,6 @@ export const getRows = (s?: string): string[] => {
|
|||||||
return str.split('#br#');
|
return str.split('#br#');
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeEscapes = (text: string): string => {
|
|
||||||
let newStr = text.replace(/\\u[\dA-F]{4}/gi, function (match) {
|
|
||||||
return String.fromCharCode(parseInt(match.replace(/\\u/g, ''), 16));
|
|
||||||
});
|
|
||||||
|
|
||||||
newStr = newStr.replace(/\\x([0-9a-f]{2})/gi, (_, c) => String.fromCharCode(parseInt(c, 16)));
|
|
||||||
newStr = newStr.replace(/\\[\d\d\d]{3}/gi, function (match) {
|
|
||||||
return String.fromCharCode(parseInt(match.replace(/\\/g, ''), 8));
|
|
||||||
});
|
|
||||||
newStr = newStr.replace(/\\[\d\d\d]{2}/gi, function (match) {
|
|
||||||
return String.fromCharCode(parseInt(match.replace(/\\/g, ''), 8));
|
|
||||||
});
|
|
||||||
|
|
||||||
return newStr;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes script tags from a text
|
* Removes script tags from a text
|
||||||
*
|
*
|
||||||
@@ -36,33 +20,7 @@ export const removeEscapes = (text: string): string => {
|
|||||||
* @returns {string} The safer text
|
* @returns {string} The safer text
|
||||||
*/
|
*/
|
||||||
export const removeScript = (txt: string): string => {
|
export const removeScript = (txt: string): string => {
|
||||||
var rs = '';
|
return DOMPurify.sanitize(txt);
|
||||||
var idx = 0;
|
|
||||||
|
|
||||||
while (idx >= 0) {
|
|
||||||
idx = txt.indexOf('<script');
|
|
||||||
if (idx >= 0) {
|
|
||||||
rs += txt.substr(0, idx);
|
|
||||||
txt = txt.substr(idx + 1);
|
|
||||||
|
|
||||||
idx = txt.indexOf('</script>');
|
|
||||||
if (idx >= 0) {
|
|
||||||
idx += 9;
|
|
||||||
txt = txt.substr(idx);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rs += txt;
|
|
||||||
idx = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let decodedText = removeEscapes(rs);
|
|
||||||
decodedText = decodedText.replaceAll(/script>/gi, '#');
|
|
||||||
decodedText = decodedText.replaceAll(/javascript:/gi, '#');
|
|
||||||
decodedText = decodedText.replaceAll(/javascript&colon/gi, '#');
|
|
||||||
decodedText = decodedText.replaceAll(/onerror=/gi, 'onerror:');
|
|
||||||
decodedText = decodedText.replaceAll(/<iframe/gi, '');
|
|
||||||
return decodedText;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const sanitizeMore = (text: string, config: MermaidConfig) => {
|
const sanitizeMore = (text: string, config: MermaidConfig) => {
|
||||||
@@ -185,5 +143,4 @@ export default {
|
|||||||
removeScript,
|
removeScript,
|
||||||
getUrl,
|
getUrl,
|
||||||
evaluate,
|
evaluate,
|
||||||
removeEscapes,
|
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user