[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1008045: bullseye-pu: package node-mermaid/8.7.0+ds+~cs27.17.17-3+deb11u1



On 21/06/2022 08:30, Salvatore Bonaccorso wrote:
Hi Yadd,

On Sat, May 28, 2022 at 09:20:40PM +0100, Adam D. Barratt wrote:
Control: tags -1 + confirmed

On Mon, 2022-03-21 at 14:09 +0100, Yadd wrote:
node-mermaid is vulnerable to XSS attack (CVE-2021-23648)


Please go ahead.

Could you fix as well CVE-2021-43861 in the next point release? Should
be then on top of the already uploaded +deb11u1.

Regards,
Salvatore

Hi,

done (8.7.0+ds+~cs27.17.17-3+deb11u2), just pushed to Bullseye queue

Regards,
Yadd
diff --git a/debian/changelog b/debian/changelog
index 32f71e8..f566922 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+node-mermaid (8.7.0+ds+~cs27.17.17-3+deb11u2) bullseye; urgency=medium
+
+  * Team upload
+  * Fix for XSS vulnerability in url sanitization (Closes: CVE-2021-43861)
+
+ -- Yadd <yadd@debian.org>  Sat, 02 Jul 2022 07:06:05 +0200
+
 node-mermaid (8.7.0+ds+~cs27.17.17-3+deb11u1) bullseye; urgency=medium
 
   * Decode html entities before sanitizing (Closes: CVE-2021-23648)
diff --git a/debian/patches/CVE-2021-43861.patch b/debian/patches/CVE-2021-43861.patch
new file mode 100644
index 0000000..418467e
--- /dev/null
+++ b/debian/patches/CVE-2021-43861.patch
@@ -0,0 +1,306 @@
+Description: Fix for XSS vulnerability in url sanitization
+Author: Knut Sveidqvist <knut.sveidqvist@ipiccolo.com>
+Origin: upstream, https://github.com/mermaid-js/mermaid/commit/066b7a0d
+Bug: https://github.com/mermaid-js/mermaid/security/advisories/GHSA-p3rp-vmj9-gv6v
+Forwarded: not-needed
+Reviewed-By: Yadd <yadd@debian.org>
+Last-Update: 2022-07-02
+
+--- /dev/null
++++ b/cypress/platform/xss16.html
+@@ -0,0 +1,106 @@
++<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-d3',
++        },
++        flowchart: {
++          // defaultRenderer: 'dagre-wrapper',
++          nodeSpacing: 10,
++    curve: 'cardinal',
++    htmlLabels: true,
++        },
++        htmlLabels: true,
++        // 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: 'loose',
++        startOnLoad: false,
++        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
++        // themeVariables: {relationLabelColor: 'red'}
++      });
++      function callback() {
++  alert('It worked');
++}
++      function xssAttack() {
++        const div = document.createElement('div');
++        div.id = 'the-malware';
++        div.className = 'malware';
++        div.innerHTML = 'XSS Succeeded';
++        document.getElementsByTagName('body')[0].appendChild(div);
++        throw new Error('XSS Succeded');
++      }
++
++      var diagram = `sequenceDiagram
++    participant Alice
++    links Alice: { "Click me!" : "javasjavascript:cript:alert('goose')" }`;
++
++// //   var diagram = "stateDiagram-v2\n";
++// //  diagram += "<img/src='1'/onerror"
++// diagram += '//via.placeholder.com/64\' width=64 />"]';
++// console.log(diagram);
++// document.querySelector('#diagram').innerHTML = diagram;
++mermaid.render('diagram', diagram, (res) => {
++  console.log(res);
++  document.querySelector('#res').innerHTML = res;
++});
++    </script>
++  </body>
++</html>
++
+--- /dev/null
++++ b/cypress/platform/xss17.html
+@@ -0,0 +1,106 @@
++<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-d3',
++        },
++        flowchart: {
++          // defaultRenderer: 'dagre-wrapper',
++          nodeSpacing: 10,
++    curve: 'cardinal',
++    htmlLabels: true,
++        },
++        htmlLabels: true,
++        // 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: 'loose',
++        startOnLoad: false,
++        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
++        // themeVariables: {relationLabelColor: 'red'}
++      });
++      function callback() {
++  alert('It worked');
++}
++      function xssAttack() {
++        const div = document.createElement('div');
++        div.id = 'the-malware';
++        div.className = 'malware';
++        div.innerHTML = 'XSS Succeeded';
++        document.getElementsByTagName('body')[0].appendChild(div);
++        throw new Error('XSS Succeded');
++      }
++
++      var diagram = `sequenceDiagram
++    participant Alice
++    link Alice: Click Me!@javasjavascript:cript:alert("goose")`;
++
++// //   var diagram = "stateDiagram-v2\n";
++// //  diagram += "<img/src='1'/onerror"
++// diagram += '//via.placeholder.com/64\' width=64 />"]';
++// console.log(diagram);
++// document.querySelector('#diagram').innerHTML = diagram;
++mermaid.render('diagram', diagram, (res) => {
++  console.log(res);
++  document.querySelector('#res').innerHTML = res;
++});
++    </script>
++  </body>
++</html>
++
+--- /dev/null
++++ b/docs/security.md
+@@ -0,0 +1,17 @@
++# Security
++The Mermaid team takes the security of Mermaid and the applications that use Mermaid seriously. This page describes how to report any vulnerabilities you may find, and lists best practices to minimize the risk of introducing a vulnerability.
++
++## Reporting vulnerabilities
++To report a vulnerability, please e-mail security@mermaid.live with a description of the issue, the steps you took to create the issue, affected versions, and if known, mitigations for the issue.
++
++We aim to reply within three working days, probably much sooner.
++
++You should expect a close collaboration as we work to resolve the issue you have reported. Please reach out to security@mermaid.live again if you do not receive prompt attention and regular updates.
++
++You may also reach out to the team via our public Slack chat channels; however, please make sure to e-mail security@mernaid.live when reporting an issue, and avoid revealing information about vulnerabilities in public as that could that could put users at risk.
++
++## Best practices
++
++Keep current with the latest Mermaid releases. We regularly update Mermaid, and these updates may fix security defects discovered in previous versions. Check the Mermaid release notes for security-related updates.
++
++Keep your application’s dependencies up to date. Make sure you upgrade your package dependencies to keep the dependencies up to date. Avoid pinning to specific versions for your dependencies and, if you do, make sure you check periodically to see if your dependencies have had security updates, and update the pin accordingly.
+--- a/src/diagrams/common/common.spec.js
++++ b/src/diagrams/common/common.spec.js
+@@ -1,4 +1,4 @@
+-import { removeScript } from './common';
++import { sanitizeText, removeScript } from './common';
+ 
+ describe('when securityLevel is antiscript, all script must be removed', function() {
+   it('should remove all script block, script inline.', function() {
+@@ -24,3 +24,15 @@
+     expect(isEqual).toEqual(true);
+   });
+ });
++
++describe('Sanitize text', function () {
++  it('should remove script tag', function () {
++    const maliciousStr = 'javajavascript:script:alert(1)';
++    const result = sanitizeText(maliciousStr, {
++      securityLevel: 'strict',
++      flowchart: { htmlLabels: true },
++    });
++    console.log('result', result);
++    expect(result).not.toContain('javascript:alert(1)');
++  });
++});
+--- a/src/diagrams/sequence/svgDraw.js
++++ b/src/diagrams/sequence/svgDraw.js
+@@ -1,4 +1,5 @@
+ import common from '../common/common';
++import { sanitizeUrl } from '@braintree/sanitize-url';
+ 
+ export const drawRect = function(elem, rectData) {
+   const rectElem = elem.append('rect');
+@@ -559,5 +560,6 @@
+   insertSequenceNumber,
+   insertArrowCrossHead,
+   getTextObj,
++  sanitizeUrl,
+   getNoteRect
+ };
+--- a/src/diagrams/sequence/svgDraw.spec.js
++++ b/src/diagrams/sequence/svgDraw.spec.js
+@@ -73,4 +73,18 @@
+       expect(rect.lower).toHaveBeenCalled();
+     });
+   });
++  describe('sanitizeUrl', function () {
++    it('it should sanitize malicious urls', function () {
++      const maliciousStr = 'javascript:script:alert(1)';
++      const result = svgDraw.sanitizeUrl(maliciousStr);
++      console.log('result', result);
++      expect(result).not.toContain('javascript:alert(1)');
++    });
++    it('it should not sanitize non dangerous urls', function () {
++      const maliciousStr = 'javajavascript:script:alert(1)';
++      const result = svgDraw.sanitizeUrl(maliciousStr);
++      console.log('result', result);
++      expect(result).not.toContain('javascript:alert(1)');
++    });
++  });
+ });
diff --git a/debian/patches/series b/debian/patches/series
index b3ba76f..7a043cc 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -2,3 +2,4 @@
 0003-Replace-moment-mini-with-moment.patch
 CVE-2021-35513.patch
 CVE-2021-23648.patch
+CVE-2021-43861.patch

Reply to: