mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-11-20 12:44:18 +01:00
Merge pull request #7075 from mermaid-js/6889-fix-escaped-p-tags-in-sandbox-mode
6889: Fix escaped <p> tags in labels when securityLevel is set to "sandbox"
This commit is contained in:
5
.changeset/brave-baths-behave.md
Normal file
5
.changeset/brave-baths-behave.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'mermaid': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: Prevent HTML tags from being escaped in sandbox label rendering
|
||||||
@@ -98,6 +98,14 @@ export const openURLAndVerifyRendering = (
|
|||||||
|
|
||||||
cy.visit(url);
|
cy.visit(url);
|
||||||
cy.window().should('have.property', 'rendered', true);
|
cy.window().should('have.property', 'rendered', true);
|
||||||
|
|
||||||
|
// Handle sandbox mode where SVG is inside an iframe
|
||||||
|
if (options.securityLevel === 'sandbox') {
|
||||||
|
cy.get('iframe').should('be.visible');
|
||||||
|
if (validation) {
|
||||||
|
cy.get('iframe').should(validation);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
cy.get('svg').should('be.visible');
|
cy.get('svg').should('be.visible');
|
||||||
// cspell:ignore viewbox
|
// cspell:ignore viewbox
|
||||||
cy.get('svg').should('not.have.attr', 'viewbox');
|
cy.get('svg').should('not.have.attr', 'viewbox');
|
||||||
@@ -105,6 +113,7 @@ export const openURLAndVerifyRendering = (
|
|||||||
if (validation) {
|
if (validation) {
|
||||||
cy.get('svg').should(validation);
|
cy.get('svg').should(validation);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (screenshot) {
|
if (screenshot) {
|
||||||
verifyScreenshot(name);
|
verifyScreenshot(name);
|
||||||
|
|||||||
@@ -79,6 +79,18 @@ describe('Flowchart v2', () => {
|
|||||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
it('6a: should render complex HTML in labels with sandbox security', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart TD
|
||||||
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
|
B --> C{Let me think}
|
||||||
|
C -->|One| D[Laptop]
|
||||||
|
C -->|Two| E[iPhone]
|
||||||
|
C -->|Three| F[fa:fa-car Car]
|
||||||
|
`,
|
||||||
|
{ securityLevel: 'sandbox', flowchart: { htmlLabels: true } }
|
||||||
|
);
|
||||||
|
});
|
||||||
it('7: should render a flowchart when useMaxWidth is true (default)', () => {
|
it('7: should render a flowchart when useMaxWidth is true (default)', () => {
|
||||||
renderGraph(
|
renderGraph(
|
||||||
`flowchart TD
|
`flowchart TD
|
||||||
|
|||||||
@@ -70,6 +70,31 @@ describe('Sanitize text', () => {
|
|||||||
});
|
});
|
||||||
expect(result).not.toContain('javascript:alert(1)');
|
expect(result).not.toContain('javascript:alert(1)');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should allow HTML tags in sandbox mode', () => {
|
||||||
|
const htmlStr = '<p>This is a <strong>bold</strong> text</p>';
|
||||||
|
const result = sanitizeText(htmlStr, {
|
||||||
|
securityLevel: 'sandbox',
|
||||||
|
flowchart: { htmlLabels: true },
|
||||||
|
});
|
||||||
|
expect(result).toContain('<p>');
|
||||||
|
expect(result).toContain('<strong>');
|
||||||
|
expect(result).toContain('</strong>');
|
||||||
|
expect(result).toContain('</p>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove script tags in sandbox mode', () => {
|
||||||
|
const maliciousStr = '<p>Hello <script>alert(1)</script> world</p>';
|
||||||
|
const result = sanitizeText(maliciousStr, {
|
||||||
|
securityLevel: 'sandbox',
|
||||||
|
flowchart: { htmlLabels: true },
|
||||||
|
});
|
||||||
|
expect(result).not.toContain('<script>');
|
||||||
|
expect(result).not.toContain('alert(1)');
|
||||||
|
expect(result).toContain('<p>');
|
||||||
|
expect(result).toContain('Hello');
|
||||||
|
expect(result).toContain('world');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('generic parser', () => {
|
describe('generic parser', () => {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export const removeScript = (txt: string): string => {
|
|||||||
const sanitizeMore = (text: string, config: MermaidConfig) => {
|
const sanitizeMore = (text: string, config: MermaidConfig) => {
|
||||||
if (config.flowchart?.htmlLabels !== false) {
|
if (config.flowchart?.htmlLabels !== false) {
|
||||||
const level = config.securityLevel;
|
const level = config.securityLevel;
|
||||||
if (level === 'antiscript' || level === 'strict') {
|
if (level === 'antiscript' || level === 'strict' || level === 'sandbox') {
|
||||||
text = removeScript(text);
|
text = removeScript(text);
|
||||||
} else if (level !== 'loose') {
|
} else if (level !== 'loose') {
|
||||||
text = breakToPlaceholder(text);
|
text = breakToPlaceholder(text);
|
||||||
|
|||||||
Reference in New Issue
Block a user