#2111 Handling 'false' as false

This commit is contained in:
Knut Sveidqvist 2021-06-03 20:47:24 +02:00
parent bf21aa8cd6
commit aa2596b457
17 changed files with 186 additions and 181 deletions

View File

@ -53,5 +53,10 @@ describe('XSS', () => {
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
it('should not allow maniplulating htmlLabels into a false positive', () => {
cy.visit('http://localhost:9000/xss4.html');
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
})

View File

@ -0,0 +1,6 @@
const div = parent.document.createElement('div');
div.id = 'the-malware';
div.className = 'malware';
div.innerHTML = 'XSS Succeeded';
parent.document.getElementsByTagName('body')[0].appendChild(div);
throw new Error('XSS Succeded');

View File

@ -67,15 +67,14 @@ stateDiagram-v2
</div>
<div class="mermaid" style="width: 100%; height: 20%;">
%%{init:{"theme":"forest", "themeVariables": {
"specialStateColor":"red",
"innerEndBackground":"lightgreen"
}}}%%
%% "specialStateColor":"red", "innerEndBackground":"lightgreen"
stateDiagram-v2
state fork [[fork]]
state join [[join]]
[*] --> fork
fork --> Test
Test --> join
fork --> join
join --> [*]
</div>
<script src="./mermaid.js"></script>

View File

@ -21,155 +21,28 @@
.mermaid svg {
/* font-size: 18px !important; */
}
.malware {
position: fixed;
bottom:0;
left:0;
right:0;
height: 150px;
background: red;
color: black;
display: flex;
display: flex;
justify-content: center;
align-items: center;
font-family: monospace;
font-size: 72px;
}
</style>
</head>
<body>
<div>info below</div>
<div>Security check</div>
<div class="flex">
<div class="mermaid2" style="width: 100%; height: 400px;">
%%{init: { "logLevel": 1, "er": {"fontSize":18 }} }%%
erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER ||--o{ ORDER : places
CUSTOMER ||--o{ INVOICE : "liable for"
DELIVERY-ADDRESS ||--o{ ORDER : receives
INVOICE ||--|{ ORDER : covers
ORDER ||--|{ ORDER-ITEM : includes
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
</div>
<div class="mermaid2" style="width: 50%; height: 400px;">
flowchart TD
A[Christmas] ==> D
A[Christmas] -->|Get money| B(Go shopping)
A[Christmas] ==> C
subgraph T ["Test"]
A
B
C
end
classDef Test fill:#F84E68,stroke:#333,color:white;
class A,T Test
classDef TestSub fill:green;
class T TestSub
linkStyle 0,1 color:orange, stroke: orange;
</div>
<div class="mermaid" style="width: 100%; height: 20%;">
graph TD
subgraph S1
sub1 -->sub2
end
subgraph S2
sub4
end
S1 --> S2
sub1 --> sub4
</div>
<div class="mermaid" style="width: 100%; height: 20%;">
graph TB
A --> B
</div>
<div class="mermaid2" style="width: 100%; height: 20%;">
stateDiagram-v2
state S1 {
sub1 -->sub2
}
state S2 {
sub4
}
S1 --> S2
sub1 --> sub4
</div>
<div class="mermaid2" style="width: 100%; height: 20%;">
requirementDiagram
requirement test_req {
id: 1
text: the test text.
risk: high
verifymethod: test
}
functionalRequirement test_req2 {
id: 1.1
text: the second test text.
risk: low
verifymethod: inspection
}
performanceRequirement test_req3 {
id: 1.2
text: the third test text.
risk: medium
verifymethod: demonstration
}
element test_entity {
type: simulation
}
element test_entity2 {
type: word doc
docRef: reqs/test_entity
}
test_entity - satisfies -> test_req2
test_req - traces -> test_req2
test_req - contains -> test_req3
test_req <- copies - test_entity2
</div>
<div class="mermaid2" style="width: 50%; height: 20%;">
flowchart LR
classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
Lorem --> Ipsum --> Dolor
class Lorem,Dolor dark
</div>
<div class="mermaid2" style="width: 50%; height: 20%;">
%%{init: {'theme': 'base' }}%%
%%{init2: { 'logLevel': 0, 'theme': 'forest'} }%%
flowchart TD
L1 --- L2
L2 --- C
M1 ---> C
R1 .-> R2
R2 <.-> C
C -->|Label 1| E1
C <-- Label 2 ---> E2
C ----> E3
C <-...-> E4
C ======> E5
</div>
<div class="mermaid2" style="width: 50%; height: 21%;">
flowchart LR
A[red text] -->|default style| B(blue text)
C([red text]) -->|default style| D[[blue text]]
E[(red text)] -->|default style| F((blue text))
G>red text] -->|default style| H{blue text}
I{{red text}} -->|default style| J[/blue text/]
K[
ed text] -->|default style| L[/blue text]
M[
ed text/] -->|default style| N[blue text]
linkStyle default color:Sienna;
style A stroke:#ff0000,fill:#ffcccc,color:#ff0000
style B stroke:#0000ff,fill:#ccccff,color:#0000ff
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
style D stroke:#0000ff,fill:#ccccff,color:#0000ff
style E stroke:#ff0000,fill:#ffcccc,color:#ff0000
style F stroke:#0000ff,fill:#ccccff,color:#0000ff
style G stroke:#ff0000,fill:#ffcccc,color:#ff0000
style H stroke:#0000ff,fill:#ccccff,color:#0000ff
style I stroke:#ff0000,fill:#ffcccc,color:#ff0000
style J stroke:#0000ff,fill:#ccccff,color:#0000ff
style K stroke:#ff0000,fill:#ffcccc,color:#ff0000
style L stroke:#0000ff,fill:#ccccff,color:#0000ff
style M stroke:#ff0000,fill:#ffcccc,color:#ff0000
style N stroke:#0000ff,fill:#ccccff,color:#0000ff
</div>
<div id="diagram" class="mermaid"></div>
<div id="res" class=""></div>
<script src="./mermaid.js"></script>
<script>
mermaid.parseError = function (err, hash) {
@ -187,7 +60,7 @@ style N stroke:#0000ff,fill:#ccccff,color:#0000ff
// defaultRenderer: 'dagre-wrapper',
nodeSpacing: 10, curve: 'cardinal', htmlLabels: true
},
htmlLabels: true,
htmlLabels: false,
// gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false },
// sequenceDiagram: { actorMargin: 300 } // deprecated
@ -195,10 +68,26 @@ style N stroke:#0000ff,fill:#ccccff,color:#0000ff
// fontFamily: 'courier',
fontSize: 18,
curve: 'basis',
securityLevel: 'loose',
securityLevel: 'strict',
startOnLoad: false
// themeVariables: {relationLabelColor: 'red'}
});
function callback(){alert('It worked');}
var diagram = "%%{init: {\"flowchart\": {\"htmlLabels\": \"false\"}} }%%\n";
diagram += "flowchart\n";
diagram += "A[\"<ifra";
diagram += "me srcdoc='<scrip";
diagram += "t src=http://localhost:9000/exploit.js>";
diagram += "</scr"
diagram += "ipt>'></iframe>\"]";
console.log(diagram);
// document.querySelector('#diagram').innerHTML = diagram;
mermaid.render('diagram', diagram, (res) => {
document.querySelector('#res').innerHTML = res;
});
</script>
</body>
</html>

View File

@ -0,0 +1,94 @@
<html>
<head>
<link
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
rel="stylesheet"
/>
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
<style>
body {
/* background: rgb(221, 208, 208); */
/* background:#333; */
font-family: 'Arial';
/* font-size: 18px !important; */
}
h1 { color: grey;}
.mermaid2 {
display: none;
}
.mermaid svg {
/* font-size: 18px !important; */
}
.malware {
position: fixed;
bottom:0;
left:0;
right:0;
height: 150px;
background: red;
color: black;
display: flex;
display: flex;
justify-content: center;
align-items: center;
font-family: monospace;
font-size: 72px;
}
</style>
</head>
<body>
<div>Security check</div>
<div class="flex">
<div id="diagram" class="mermaid"></div>
<div id="res" class=""></div>
<script src="./mermaid.js"></script>
<script>
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
theme: 'forest',
arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0,
state: {
defaultRenderer: 'dagre-wrapper',
},
flowchart: {
// defaultRenderer: 'dagre-wrapper',
nodeSpacing: 10, curve: 'cardinal', htmlLabels: true
},
htmlLabels: false,
// gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false },
// sequenceDiagram: { actorMargin: 300 } // deprecated
// fontFamily: '"times", sans-serif',
// fontFamily: 'courier',
fontSize: 18,
curve: 'basis',
securityLevel: 'strict',
startOnLoad: false,
secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize']
// themeVariables: {relationLabelColor: 'red'}
});
function callback(){alert('It worked');}
var diagram = "%%{init: {\"flowchart\": {\"htmlLabels\": \"true\"}} }%%\n";
diagram += "flowchart\n";
diagram += "A[\"<ifra";
diagram += "me srcdoc='<scrip";
diagram += "t src=http://localhost:9000/exploit.js>";
diagram += "</scr"
diagram += "ipt>'></iframe>\"]";
console.log(diagram);
// document.querySelector('#diagram').innerHTML = diagram;
mermaid.render('diagram', diagram, (res) => {
document.querySelector('#res').innerHTML = res;
});
</script>
</body>
</html>

View File

@ -3,6 +3,7 @@ import { log } from '../logger';
import createLabel from './createLabel';
import { select } from 'd3';
import { getConfig } from '../config';
import { evaluate } from '../diagrams/common/common';
const rect = (parent, node) => {
log.trace('Creating subgraph rect for ', node.id, node);
@ -26,7 +27,7 @@ const rect = (parent, node) => {
// Get the size of the label
let bbox = text.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = text.children[0];
const dv = select(text);
bbox = div.getBoundingClientRect();
@ -132,7 +133,7 @@ const roundedWithTitle = (parent, node) => {
// Get the size of the label
let bbox = text.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = text.children[0];
const dv = select(text);
bbox = div.getBoundingClientRect();
@ -170,7 +171,10 @@ const roundedWithTitle = (parent, node) => {
'translate(' +
(node.x - bbox.width / 2) +
', ' +
(node.y - node.height / 2 - node.padding / 3 + (getConfig().flowchart.htmlLabels ? 5 : 3)) +
(node.y -
node.height / 2 -
node.padding / 3 +
(evaluate(getConfig().flowchart.htmlLabels) ? 5 : 3)) +
')'
);

View File

@ -1,7 +1,8 @@
import { select } from 'd3';
import { log } from '../logger'; // eslint-disable-line
import { evaluate } from '../diagrams/common/common';
// let vertexNode;
// if (getConfig().flowchart.htmlLabels) {
// if (evaluate(getConfig().flowchart.htmlLabels)) {
// // TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
// const node = {
// label: vertexText.replace(/fa[lrsb]?:fa-[\w-]+/g, s => `<i class='${s.replace(':', ' ')}'></i>`)
@ -86,7 +87,7 @@ function addHtmlLabel(node) {
const createLabel = (_vertexText, style, isTitle, isNode) => {
let vertexText = _vertexText || '';
if (typeof vertexText === 'object') vertexText = vertexText[0];
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
vertexText = vertexText.replace(/\\n|\n/g, '<br />');
log.info('vertexText' + vertexText);

View File

@ -4,7 +4,7 @@ import createLabel from './createLabel';
import { line, curveBasis, select } from 'd3';
import { getConfig } from '../config';
import utils from '../utils';
// import { calcLabelPosition } from '../utils';
import { evaluate } from '../diagrams/common/common';
let edgeLabels = {};
let terminalLabels = {};
@ -27,7 +27,7 @@ export const insertEdgeLabel = (elem, edge) => {
// Center the label
let bbox = labelElement.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = labelElement.children[0];
const dv = select(labelElement);
bbox = div.getBoundingClientRect();

View File

@ -6,6 +6,7 @@ import intersect from './intersect/index.js';
import createLabel from './createLabel';
import note from './shapes/note';
import { parseMember } from '../diagrams/class/svgDraw';
import { evaluate } from '../diagrams/common/common';
const question = (parent, node) => {
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
@ -370,7 +371,7 @@ const rectWithTitle = (parent, node) => {
const text = label.node().appendChild(createLabel(title, node.labelStyle, true, true));
let bbox;
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = text.children[0];
const dv = select(text);
bbox = div.getBoundingClientRect();
@ -386,7 +387,7 @@ const rectWithTitle = (parent, node) => {
createLabel(textRows.join ? textRows.join('<br/>') : textRows, node.labelStyle, true, true)
);
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = descr.children[0];
const dv = select(descr);
bbox = div.getBoundingClientRect();
@ -648,7 +649,7 @@ const class_box = (parent, node) => {
.node()
.appendChild(createLabel(interfaceLabelText, node.labelStyle, true, true));
let interfaceBBox = interfaceLabel.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = interfaceLabel.children[0];
const dv = select(interfaceLabel);
interfaceBBox = div.getBoundingClientRect();
@ -670,7 +671,7 @@ const class_box = (parent, node) => {
.appendChild(createLabel(classTitleString, node.labelStyle, true, true));
select(classTitleLabel).attr('class', 'classTitle');
let classTitleBBox = classTitleLabel.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = classTitleLabel.children[0];
const dv = select(classTitleLabel);
classTitleBBox = div.getBoundingClientRect();
@ -688,7 +689,7 @@ const class_box = (parent, node) => {
.node()
.appendChild(createLabel(parsedText, node.labelStyle, true, true));
let bbox = lbl.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = lbl.children[0];
const dv = select(lbl);
bbox = div.getBoundingClientRect();
@ -711,7 +712,7 @@ const class_box = (parent, node) => {
.node()
.appendChild(createLabel(parsedText, node.labelStyle, true, true));
let bbox = lbl.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = lbl.children[0];
const dv = select(lbl);
bbox = div.getBoundingClientRect();
@ -791,7 +792,7 @@ const class_box = (parent, node) => {
});
//
// let bbox;
// if (getConfig().flowchart.htmlLabels) {
// if (evaluate(getConfig().flowchart.htmlLabels)) {
// const div = interfaceLabel.children[0];
// const dv = select(interfaceLabel);
// bbox = div.getBoundingClientRect();
@ -807,7 +808,7 @@ const class_box = (parent, node) => {
// .node()
// .appendChild(createLabel(textRows.join('<br/>'), node.labelStyle, true, true));
// if (getConfig().flowchart.htmlLabels) {
// if (evaluate(getConfig().flowchart.htmlLabels)) {
// const div = descr.children[0];
// const dv = select(descr);
// bbox = div.getBoundingClientRect();

View File

@ -1,6 +1,7 @@
import createLabel from '../createLabel';
import { getConfig } from '../../config';
import { select } from 'd3';
import { evaluate } from '../../diagrams/common/common';
export const labelHelper = (parent, node, _classes, isNode) => {
let classes;
if (!_classes) {
@ -27,7 +28,7 @@ export const labelHelper = (parent, node, _classes, isNode) => {
// Get the size of the label
let bbox = text.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = text.children[0];
const dv = select(text);
bbox = div.getBoundingClientRect();

View File

@ -57,7 +57,7 @@ export const addClasses = function(classes, g) {
// We create a SVG label, either by delegating to addHtmlLabel or manually
// let vertexNode;
// if (getConfig().flowchart.htmlLabels) {
// if (evaluate(getConfig().flowchart.htmlLabels)) {
// const node = {
// label: vertexText.replace(
// /fa[lrsb]?:fa-[\w-]+/g,

View File

@ -90,6 +90,8 @@ const getUrl = useAbsolute => {
return url;
};
export const evaluate = val => (val === 'false' || val === false ? false : true);
export default {
getRows,
sanitizeText,
@ -97,5 +99,6 @@ export default {
splitBreaks,
lineBreakRegex,
removeScript,
getUrl
getUrl,
evaluate
};

View File

@ -8,7 +8,7 @@ import { getConfig } from '../../config';
import { render } from '../../dagre-wrapper/index.js';
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
import { log } from '../../logger';
import common from '../common/common';
import common, { evaluate } from '../common/common';
import { interpolateToCurve, getStylesFromArray, configureSvgSize } from '../../utils';
const conf = {};
@ -48,7 +48,7 @@ export const addVertices = function(vert, g, svgId) {
// We create a SVG label, either by delegating to addHtmlLabel or manually
let vertexNode;
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
const node = {
label: vertexText.replace(
@ -292,7 +292,7 @@ export const addEdges = function(edges, g) {
edgeData.arrowheadStyle = 'fill: #333';
edgeData.labelpos = 'c';
}
// if (getConfig().flowchart.htmlLabels && false) {
// if (evaluate(getConfig().flowchart.htmlLabels) && false) {
// // eslint-disable-line
// edgeData.labelType = 'html';
// edgeData.label = `<span id="L-${linkId}" class="edgeLabel L-${linkNameStart}' L-${linkNameEnd}">${edge.text}</span>`;

View File

@ -8,7 +8,7 @@ import { getConfig } from '../../config';
import dagreD3 from 'dagre-d3';
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
import { log } from '../../logger';
import common from '../common/common';
import common, { evaluate } from '../common/common';
import { interpolateToCurve, getStylesFromArray, configureSvgSize } from '../../utils';
import flowChartShapes from './flowChartShapes';
@ -49,7 +49,7 @@ export const addVertices = function(vert, g, svgId) {
// We create a SVG label, either by delegating to addHtmlLabel or manually
let vertexNode;
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
const node = {
label: vertexText.replace(
@ -228,7 +228,7 @@ export const addEdges = function(edges, g) {
edgeData.arrowheadStyle = 'fill: #333';
edgeData.labelpos = 'c';
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
edgeData.labelType = 'html';
edgeData.label = `<span id="L-${linkId}" class="edgeLabel L-${linkNameStart}' L-${linkNameEnd}">${edge.text.replace(
/fa[lrsb]?:fa-[\w-]+/g,
@ -451,7 +451,7 @@ export const draw = function(text, id) {
}
// Add label rects for non html labels
if (!conf.htmlLabels || true) { // eslint-disable-line
if (!evaluate(conf.htmlLabels) || true) { // eslint-disable-line
const labels = document.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
for (let k = 0; k < labels.length; k++) {
const label = labels[k];

View File

@ -3,7 +3,7 @@ import { select } from 'd3';
import stateDb from './stateDb';
import state from './parser/stateDiagram';
import { getConfig } from '../../config';
import { evaluate } from '../common/common';
import { render } from '../../dagre-wrapper/index.js';
import { log } from '../../logger';
import { configureSvgSize } from '../../utils';
@ -295,7 +295,7 @@ export const draw = function(text, id) {
svg.attr('viewBox', vBox);
// Add label rects for non html labels
if (!conf.htmlLabels) {
if (!evaluate(conf.htmlLabels)) {
const labels = document.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
for (let k = 0; k < labels.length; k++) {
const label = labels[k];

View File

@ -137,7 +137,8 @@ const initialize = function(config) {
mermaid.startOnLoad = config.mermaid.startOnLoad;
}
if (typeof config.mermaid.htmlLabels !== 'undefined') {
mermaid.htmlLabels = config.mermaid.htmlLabels;
mermaid.htmlLabels =
config.mermaid.htmlLabels === 'false' || config.mermaid.htmlLabels === false ? false : true;
}
}
mermaidAPI.initialize(config);

View File

@ -54,6 +54,7 @@ import journeyDb from './diagrams/user-journey/journeyDb';
import journeyRenderer from './diagrams/user-journey/journeyRenderer';
import journeyParser from './diagrams/user-journey/parser/journey';
import errorRenderer from './errorRenderer';
import { evaluate } from './diagrams/common/common';
// import * as configApi from './config';
// // , {
// // setConfig,
@ -297,8 +298,9 @@ const render = function(id, _txt, cb, container) {
// classDef
if (graphType === 'flowchart' || graphType === 'flowchart-v2' || graphType === 'graph') {
const classes = flowRenderer.getClasses(txt);
const htmlLabels = evaluate(cnf.htmlLabels) || evaluate(cnf.flowchart.htmlLabels);
for (const className in classes) {
if (cnf.htmlLabels || cnf.flowchart.htmlLabels) {
if (htmlLabels) {
userStyles += `\n.${className} > * { ${classes[className].styles.join(
' !important; '
)} !important; }`;
@ -306,7 +308,6 @@ const render = function(id, _txt, cb, container) {
' !important; '
)} !important; }`;
} else {
// console.log('classes[className].styles', classes[className].styles, cnf.htmlLabels);
userStyles += `\n.${className} path { ${classes[className].styles.join(
' !important; '
)} !important; }`;