VYPR
Moderate severityGHSA Advisory· Published May 11, 2026· Updated May 11, 2026

Mermaid Gantt Charts are vulnerable to an Infinite Loop DoS

CVE-2026-41150

Description

Impact

Mermaid v11.14.0 and earlier are vulnerable to a denial-of-service attack when rendering gantt charts, if they use the `excludes` attribute to exclude all dates.

Example:

gantt
  excludes monday,tuesday,wednesday,thursday,friday,saturday,sunday
  DoS :2025-01-01, 1d

mermaid.parse is unaffected, unless you then call the ganttDb.getTasks() (which is called when rendering a diagram).

Patches

This has been patched in:

Workarounds

There are no workarounds available without updating to a newer version of mermaid.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Mermaid v11.14.0 and earlier vulnerable to denial-of-service via gantt charts when excludes removes all dates, causing an infinite loop.

Vulnerability

Mermaid [1] versions 11.14.0 and earlier contain a denial-of-service vulnerability in the Gantt chart rendering. The fixTaskDates function enters an infinite loop when the excludes attribute removes all weekdays (e.g., excludes monday,...,sunday), because no valid end date can be found [2][3].

Exploitation

An attacker can craft a Gantt diagram string with an excludes line covering all days and a task date range. When the diagram is rendered via ganttDb.getTasks(), the application hangs indefinitely, causing a denial-of-service condition. The diagram can be embedded in markdown or user input processed by Mermaid, requiring no special privileges.

Impact

Successful exploitation causes the application to become unresponsive, leading to a denial-of-service. This can affect services that render user-supplied Mermaid diagrams, such as documentation generators or live editors.

Mitigation

The vulnerability is patched in Mermaid versions 11.15.0 [2] and 10.9.6 [4]. Users should upgrade to these versions or later. No workarounds are available.

AI Insight generated on May 18, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
mermaidnpm
>= 11.0.0-alpha.1, < 11.15.011.15.0
mermaidnpm
< 10.9.610.9.6

Affected products

2
  • Mermaid Js/MermaidGHSA2 versions
    <= 10.9.5+ 1 more
    • (no CPE)range: <= 10.9.5
    • (no CPE)range: <= 11.14.0

Patches

2
a59ea5617471

fix(gantt): limit loop if excluding all dates

https://github.com/mermaid-js/mermaidAlois KlinkMar 30, 2026via ghsa
2 files changed · +22 2
  • packages/mermaid/src/diagrams/gantt/ganttDb.js+9 2 modified
    @@ -231,21 +231,28 @@ const checkTaskDates = function (task, dateFormat, excludes, includes) {
      * @param {dayjs.Dayjs} startTime - The start time.
      * @param {dayjs.Dayjs} endTime - The original end time (will return a different end time if it's invalid).
      * @param {string} dateFormat - Dayjs date format string.
    - * @param {*} excludes
    - * @param {*} includes
    + * @param {string[]} excludes - Dates or days to exclude.
    + * @param {string[]} includes - Dates to always include, even if they match the excludes.
      * @returns {[endTime: dayjs.Dayjs, renderEndTime: Date | null]} The new `endTime`, and the end time to render.
      * `renderEndTime` may be `null` if `startTime` is newer than `endTime`.
    + * @throws {Error} If a valid end time cannot be found after 10,000 iterations.
      */
     const fixTaskDates = function (startTime, endTime, dateFormat, excludes, includes) {
       let invalid = false;
       let renderEndTime = null;
    +  const maxEndTime = endTime.add(10000, 'd');
       while (startTime <= endTime) {
         if (!invalid) {
           renderEndTime = endTime.toDate();
         }
         invalid = isInvalidDate(startTime, dateFormat, excludes, includes);
         if (invalid) {
           endTime = endTime.add(1, 'd');
    +      if (endTime > maxEndTime) {
    +        throw new Error(
    +          'Failed to find a valid date that was not excluded by `excludes` after 10,000 iterations.'
    +        );
    +      }
         }
         startTime = startTime.add(1, 'd');
       }
    
  • packages/mermaid/src/diagrams/gantt/ganttDb.spec.ts+13 0 modified
    @@ -267,6 +267,19 @@ describe('when using the ganttDb', function () {
         expect(tasks[6].task).toEqual('test7');
       });
     
    +  it('should not infinite loop when excluding everything', function () {
    +    ganttDb.setDateFormat('YYYY-MM-DD');
    +    ganttDb.setExcludes('weekends,monday,tuesday,wednesday,thursday,friday');
    +    ganttDb.addSection('weekends skip test');
    +    ganttDb.addTask('test1', 'id1,2019-02-01,7d');
    +
    +    expect(() => ganttDb.getTasks()).toThrowError('Failed to find a valid date');
    +
    +    // Fridays are now allowed, so it should not throw an error
    +    ganttDb.setExcludes('weekends,monday,tuesday,wednesday,thursday');
    +    expect(() => ganttDb.getTasks()).not.toThrow();
    +  });
    +
       it('should maintain the order in which tasks are created', function () {
         ganttDb.setAccTitle('Project Execution');
         ganttDb.setDateFormat('YYYY-MM-DD');
    
faafb5d49106

fix(gantt): limit loop if excluding all dates

https://github.com/mermaid-js/mermaidAlois KlinkMar 30, 2026via ghsa
3 files changed · +28 2
  • .changeset/common-parents-serve.md+5 0 added
    @@ -0,0 +1,5 @@
    +---
    +'mermaid': patch
    +---
    +
    +fix(gantt): add iteration limit for `excludes` field
    
  • packages/mermaid/src/diagrams/gantt/ganttDb.js+9 2 modified
    @@ -245,21 +245,28 @@ const checkTaskDates = function (task, dateFormat, excludes, includes) {
      * @param {dayjs.Dayjs} startTime - The start time.
      * @param {dayjs.Dayjs} endTime - The original end time (will return a different end time if it's invalid).
      * @param {string} dateFormat - Dayjs date format string.
    - * @param {*} excludes
    - * @param {*} includes
    + * @param {string[]} excludes - Dates or days to exclude.
    + * @param {string[]} includes - Dates to always include, even if they match the excludes.
      * @returns {[endTime: dayjs.Dayjs, renderEndTime: Date | null]} The new `endTime`, and the end time to render.
      * `renderEndTime` may be `null` if `startTime` is newer than `endTime`.
    + * @throws {Error} If a valid end time cannot be found after 10,000 iterations.
      */
     const fixTaskDates = function (startTime, endTime, dateFormat, excludes, includes) {
       let invalid = false;
       let renderEndTime = null;
    +  const maxEndTime = endTime.add(10000, 'd');
       while (startTime <= endTime) {
         if (!invalid) {
           renderEndTime = endTime.toDate();
         }
         invalid = isInvalidDate(startTime, dateFormat, excludes, includes);
         if (invalid) {
           endTime = endTime.add(1, 'd');
    +      if (endTime > maxEndTime) {
    +        throw new Error(
    +          'Failed to find a valid date that was not excluded by `excludes` after 10,000 iterations.'
    +        );
    +      }
         }
         startTime = startTime.add(1, 'd');
       }
    
  • packages/mermaid/src/diagrams/gantt/ganttDb.spec.ts+14 0 modified
    @@ -282,6 +282,20 @@ describe('when using the ganttDb', function () {
         expect(tasks[0].task).toEqual('test1');
       });
     
    +  it('should not infinite loop when excluding everything', function () {
    +    ganttDb.setDateFormat('YYYY-MM-DD');
    +    ganttDb.setExcludes('weekends,monday,tuesday,wednesday,thursday,friday');
    +    ganttDb.setWeekend('saturday');
    +    ganttDb.addSection('weekends skip test');
    +    ganttDb.addTask('test1', 'id1,2019-02-01,7d');
    +
    +    expect(() => ganttDb.getTasks()).toThrowError('Failed to find a valid date');
    +
    +    // Fridays are now allowed, so it should not throw an error
    +    ganttDb.setExcludes('weekends,monday,tuesday,wednesday,thursday');
    +    expect(() => ganttDb.getTasks()).not.toThrow();
    +  });
    +
       it('should maintain the order in which tasks are created', function () {
         ganttDb.setAccTitle('Project Execution');
         ganttDb.setDateFormat('YYYY-MM-DD');
    

Vulnerability mechanics

AI mechanics synthesis has not run for this CVE yet.

References

6

News mentions

0

No linked articles in our index yet.