mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-10-31 02:44:17 +01:00 
			
		
		
		
	 803e2e14be
			
		
	
	803e2e14be
	
	
	
		
			
			* upstream/develop: (68 commits) fix: sanitize addHtmlLabel in createLabel docs(integrations): update Tiki to Tiki Wiki CMS Groupware community in list cms/ecm to avoid confusion updated lock file #6856 Exposing elk configuration forceNodeModelOrder and considerModelOrder to the mermaid configuration chore: Modify changeset Update .changeset/strong-laws-confess.md fix: fallback to raw text instead of rendering empty boxes when `htmlLabels: false` chore: Modify changeset [autofix.ci] apply automated fixes test: Add E2E test for unsupported markdown Create strong-laws-confess.md fix: Remove data loss when unsupported markdown is encountered Apply suggestion from @sidharthv96 Add changeset and integration test chore: update E2E timings Make elk not force model order, but strongly consider it instead chore(deps): update peter-evans/create-pull-request digest to 1310d7d added changeset Fix border style for hand drawn shapes test: Verify label is sanitized ...
		
			
				
	
	
		
			178 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			178 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import { imgSnapshotTest, mermaidUrl, utf8ToB64 } from '../../helpers/util.ts';
 | |
| describe('XSS', () => {
 | |
|   it('should handle xss in tags', () => {
 | |
|     const str =
 | |
|       'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In19';
 | |
| 
 | |
|     const url = mermaidUrl(str, {}, true);
 | |
| 
 | |
|     cy.visit(url);
 | |
|     cy.wait(1000).then(() => {
 | |
|       cy.get('.mermaid').should('exist');
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   it('should not allow tags in the css', () => {
 | |
|     const str =
 | |
|       'eyJjb2RlIjoiJSV7aW5pdDogeyAnZm9udEZhbWlseSc6ICdcXFwiPjwvc3R5bGU+PGltZyBzcmM9eCBvbmVycm9yPXhzc0F0dGFjaygpPid9IH0lJVxuZ3JhcGggTFJcbiAgICAgQSAtLT4gQiIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9';
 | |
| 
 | |
|     const url = mermaidUrl(
 | |
|       str,
 | |
|       {
 | |
|         theme: 'default',
 | |
|         flowchart: {
 | |
|           htmlMode: false,
 | |
|         },
 | |
|       },
 | |
|       true
 | |
|     );
 | |
| 
 | |
|     cy.visit(url);
 | |
|     cy.wait(1000).then(() => {
 | |
|       cy.get('#the-malware').should('not.exist');
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   it('should handle xss in tags in non-html mode', () => {
 | |
|     const str =
 | |
|       'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX19';
 | |
| 
 | |
|     const url = mermaidUrl(
 | |
|       str,
 | |
|       {
 | |
|         theme: 'default',
 | |
|         flowchart: {
 | |
|           htmlMode: false,
 | |
|         },
 | |
|       },
 | |
|       true
 | |
|     );
 | |
| 
 | |
|     cy.visit(url);
 | |
|     cy.wait(1000);
 | |
| 
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
| 
 | |
|   it('should not allow changing the __proto__ attribute using config', () => {
 | |
|     cy.visit('http://localhost:9000/xss2.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should not allow manipulating htmlLabels into a false positive', () => {
 | |
|     cy.visit('http://localhost:9000/xss4.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should not allow manipulating antiscript to run javascript', () => {
 | |
|     cy.visit('http://localhost:9000/xss5.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should not allow manipulating antiscript to run javascript using onerror', () => {
 | |
|     cy.visit('http://localhost:9000/xss6.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should not allow manipulating antiscript to run javascript using onerror in state diagrams with dagre wrapper', () => {
 | |
|     cy.visit('http://localhost:9000/xss8.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should not allow manipulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
 | |
|     cy.on('uncaught:exception', (_err, _runnable) => {
 | |
|       return false; // continue rendering even if there if mermaid throws an error
 | |
|     });
 | |
|     cy.visit('http://localhost:9000/xss9.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should not allow manipulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
 | |
|     cy.visit('http://localhost:9000/xss10.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should not allow manipulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
 | |
|     cy.visit('http://localhost:9000/xss11.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should not allow manipulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
 | |
|     cy.visit('http://localhost:9000/xss12.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should not allow manipulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
 | |
|     cy.visit('http://localhost:9000/xss13.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should not allow manipulating antiscript to run javascript iframes in class diagrams', () => {
 | |
|     cy.visit('http://localhost:9000/xss14.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should sanitize cardinalities properly in class diagrams', () => {
 | |
|     cy.visit('http://localhost:9000/xss18.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should sanitize colons properly', () => {
 | |
|     cy.visit('http://localhost:9000/xss20.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('a').click('');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should sanitize colons properly', () => {
 | |
|     cy.visit('http://localhost:9000/xss21.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('a').click('');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should sanitize backticks in class names properly', () => {
 | |
|     cy.visit('http://localhost:9000/xss24.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
|   it('should sanitize backticks block diagram labels properly', () => {
 | |
|     cy.visit('http://localhost:9000/xss25.html');
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
| 
 | |
|   it('should sanitize icon labels in architecture diagrams', () => {
 | |
|     const str = JSON.stringify({
 | |
|       code: `architecture-beta
 | |
|     group api(cloud)[API]
 | |
|     service db "<img src=x onerror=\\"xssAttack()\\">" [Database] in api`,
 | |
|     });
 | |
|     imgSnapshotTest(utf8ToB64(str), {}, true);
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
| 
 | |
|   it('should sanitize katex blocks', () => {
 | |
|     const str = JSON.stringify({
 | |
|       code: `sequenceDiagram
 | |
|     participant A as Alice<img src="x" onerror="xssAttack()">$$\\text{Alice}$$
 | |
|     A->>John: Hello John, how are you?`,
 | |
|     });
 | |
|     imgSnapshotTest(utf8ToB64(str), {}, true);
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
| 
 | |
|   it('should sanitize labels', () => {
 | |
|     const str = JSON.stringify({
 | |
|       code: `erDiagram
 | |
|     "<img src=x onerror=xssAttack()>" ||--|| ENTITY2 : "<img src=x onerror=xssAttack()>"
 | |
|     `,
 | |
|     });
 | |
|     imgSnapshotTest(utf8ToB64(str), {}, true);
 | |
|     cy.wait(1000);
 | |
|     cy.get('#the-malware').should('not.exist');
 | |
|   });
 | |
| });
 |