Problem/Motivation

Drupal core currently includes Underscore.js 1.13.7, which is affected by CVE-2026-27601.

In versions prior to 1.13.8, the functions .flatten and .isEqual use recursion without a depth limit. Under specific conditions, this can lead to a stack overflow and be exploited as a Denial of Service (DoS).

The vulnerability is classified as:

CWE-770: Allocation of Resources Without Limits or Throttling

CVSS v4 Base Score: 8.2 (HIGH)

CVSS v3.1 Base Score: 7.5 (HIGH)

The issue is fixed in Underscore.js 1.13.8.

References:

https://github.com/jashkenas/underscore/security/advisories/GHSA-qpx9-hp...

https://underscorejs.org/#1.13.8

Create a deeply nested recursive data structure from untrusted input (e.g., via JSON.parse without depth validation).

Pass the structure to .flatten without specifying a finite depth limit,
or compare two attacker-controlled structures using .isEqual.

Trigger a stack overflow leading to a Denial of Service condition.

Update the bundled Underscore.js library in Drupal core from 1.13.7 to 1.13.8, which includes the upstream fix.

Update the Underscore.js library to version 1.13.8.

Verify no regressions in core JavaScript behaviors.

Confirm library metadata and license headers remain accurate.

Run automated tests.

Proposed resolution

Updated Underscore.js from 1.13.7 to 1.13.8 to address CVE-2026-27601 (Denial of Service vulnerability related to uncontrolled recursion in .flatten and .isEqual).

Issue fork drupal-3578028

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

alfaro created an issue. See original summary.

cilefen’s picture

Version: 10.5.x-dev » main
Status: Active » Needs work
Issue tags: -Update Underscore.js to the latest version +Needs merge request

longwave made their first commit to this issue’s fork.

longwave’s picture

Status: Needs work » Needs review
Issue tags: -Needs merge request

MR is the result of:

cd core
yarn add -D underscore
yarn vendor-update

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

LGTM, since it’s a patch release don’t see anything that broke

quietone’s picture

Title: Drupal core currently includes Underscore.js 1.13.7, which is affected by CVE-2026-27601 » Update underscore.js to 1.13.8

  • catch committed d6d3621d on main
    task: #3578028 Update underscore.js to 1.13.8
    
    By: alfaro
    By: longwave
    

  • catch committed a0e1b4ec on 11.3.x
    task: #3578028 Update underscore.js to 1.13.8
    
    By: alfaro
    By: longwave
    (...

  • catch committed 8bc541e2 on 11.x
    task: #3578028 Update underscore.js to 1.13.8
    
    By: alfaro
    By: longwave
    (...
catch’s picture

Version: main » 11.3.x-dev
Status: Reviewed & tested by the community » Fixed

Committed/pushed to main, 11.x, and 11.3.x, thanks!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

xjm’s picture

Status: Closed (fixed) » Needs work

Reopening this to explore the possibility of backport. We could use at least a 10.6 MR, and we can discuss whether to backport it to 11.2 and 10.5.

ashetkar made their first commit to this issue’s fork.

xjm’s picture

According to the backport policy, the issue should be committed to 10.6.x first. Additionally, we haven't determined yet whether this is safe to backport to the patch release versions (11.2.x and 10.5.x).

It looks like the needed changes to the lockfile and package.json are missing from the new MR?

quietone’s picture

Issue tags: +DrupalSouth

This would be a good task to work on for Contribution day tomorrow.

xjm’s picture

georgebc made their first commit to this issue’s fork.

georgebc’s picture

Status: Needs work » Needs review

Opened MR for the 10.6.x backport. Ran cd core && yarn add -D underscore && yarn vendor-update. Includes the lockfile and package.json changes.

xjm changed the visibility of the branch 3578028-underscorejs-fix-10.x to hidden.

quietone’s picture

As soon as I made that comment I looked at the previous commits and see that this was changed to the carat type constraint string.
However, this is for Drupal 10, should this stay with the tilde version so underscore.js stays on the current minor?

xjm’s picture

I think we don't want to change the constraint type; those are chosen on purpose.

xjm’s picture

xjm’s picture

Issue summary: View changes
StatusFileSize
new1.37 MB
new1.53 MB

I used the following steps (within the core directory) based on the core dependency update instructions:

  1. rm -rf node_modules; yarn install
    
  2. yarn outdated
    

    (And confirmed that underscore was listed.)
     

  3. Two options: We usually increase the required minimum patch version if the the vulnerability is exploitable in core and leave it alone if not, at least for backport versions.

    When increasing the constraint:

    1. Edit core/package.json and manually increase the constraint to ~1.13.8.
    2. yarn install

    When not increasing the constraint:

    yarn upgrade underscore
    
  4. yarn vendor-update
    
  5. yarn build
    

    (A no-op in the case of this issue; it does not affect the built libraries.)

  6. yarn lint:css
    yarn lint:core-js-passing
    

    (No issues.) :)

Fortunately, the only differences between the provided MR and the strategy where we increase the constraint is only the carat versus the tilde in the package.json and lockfile:

colored word diff showing two ^ changed to ~

If we choose not to increase the constraint it's similarly simple:

colored word diff showing two small changes

quietone’s picture

Version: 11.3.x-dev » 10.6.x-dev

I updated the 10.6.x MR per the last comments by xjm.

What I did

  1. Edited package.json to update the patch version number
  2. yarn install
  3. yarn build

The only changes were to package.json and yarn.lock