mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-11-03 04:14:15 +01:00
Merge pull request from GHSA-x3vm-38hw-55wf
CSS Injection security issue
This commit is contained in:
@@ -385,6 +385,8 @@ const render = function (id, _txt, cb, container) {
|
||||
|
||||
let userStyles = '';
|
||||
// user provided theme CSS
|
||||
// If you add more configuration driven data into the user styles make sure that the value is
|
||||
// sanitized bye the santiizeCSS function
|
||||
if (cnf.themeCSS !== undefined) {
|
||||
userStyles += `\n${cnf.themeCSS}`;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import sequence from './diagrams/sequence/styles';
|
||||
import stateDiagram from './diagrams/state/styles';
|
||||
import journey from './diagrams/user-journey/styles';
|
||||
import c4 from './diagrams/c4/styles';
|
||||
import { log } from './logger';
|
||||
|
||||
const themes = {
|
||||
flowchart,
|
||||
@@ -30,7 +31,10 @@ const themes = {
|
||||
c4,
|
||||
};
|
||||
|
||||
export const calcThemeVariables = (theme, userOverRides) => theme.calcColors(userOverRides);
|
||||
export const calcThemeVariables = (theme, userOverRides) => {
|
||||
log.info('userOverides', userOverRides);
|
||||
return theme.calcColors(userOverRides);
|
||||
};
|
||||
|
||||
const getStyles = (type, userStyles, options) => {
|
||||
return ` {
|
||||
|
||||
35
src/utils.js
35
src/utils.js
@@ -1032,6 +1032,14 @@ export const directiveSanitizer = (args) => {
|
||||
log.debug('sanitizing themeCss option');
|
||||
args[key] = sanitizeCss(args[key]);
|
||||
}
|
||||
if (key.indexOf('fontFamily') >= 0) {
|
||||
log.debug('sanitizing fontFamily option');
|
||||
args[key] = sanitizeCss(args[key]);
|
||||
}
|
||||
if (key.indexOf('altFontFamily') >= 0) {
|
||||
log.debug('sanitizing altFontFamily option');
|
||||
args[key] = sanitizeCss(args[key]);
|
||||
}
|
||||
if (configKeys.indexOf(key) < 0) {
|
||||
log.debug('sanitize deleting option', key);
|
||||
delete args[key];
|
||||
@@ -1044,11 +1052,32 @@ export const directiveSanitizer = (args) => {
|
||||
});
|
||||
}
|
||||
}
|
||||
if (args.themeVariables) {
|
||||
const kArr = Object.keys(args.themeVariables);
|
||||
for (let i = 0; i < kArr.length; i++) {
|
||||
const k = kArr[i];
|
||||
const val = args.themeVariables[k];
|
||||
if (val && val.match && !val.match(/^[a-zA-Z0-9#,";()%. ]+$/)) {
|
||||
args.themeVariables[k] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
log.debug('After sanitization', args);
|
||||
};
|
||||
export const sanitizeCss = (str) => {
|
||||
const stringsearch = 'o';
|
||||
const startCnt = (str.match(/\{/g) || []).length;
|
||||
const endCnt = (str.match(/\}/g) || []).length;
|
||||
let startCnt = 0;
|
||||
let endCnt = 0;
|
||||
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
if (startCnt < endCnt) {
|
||||
return '{ /* ERROR: Unbalanced CSS */ }';
|
||||
}
|
||||
if (str[i] === '{') {
|
||||
startCnt++;
|
||||
} else if (str[i] === '}') {
|
||||
endCnt++;
|
||||
}
|
||||
}
|
||||
if (startCnt !== endCnt) {
|
||||
return '{ /* ERROR: Unbalanced CSS */ }';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user