Javascript Version Disclosure

Created on 10 April 2025, 30 days ago

Problem/Motivation

We have several sites that are scanned by Invicti / Netsparker to identify potential security concerns.
They repeatedly have the following finding:

Invicti Enterprise identified a version disclosure (Jquery) in the target web server's HTTP response.This information can help an attacker gain a greater understanding of the systems in use and potentially develop further attacks targeted at the specific version of Jquery (or other javascript libraries).

After reaching out to find what they are referring to, it is this

  <script src="/core/assets/vendor/jquery/jquery.min.js?v=3.7.1"></script>
  <script src="/core/misc/touchevents-test.js?v=10.4.5"></script>
  <script src="/core/assets/vendor/backbone/backbone-min.js?v=1.6.0"></script>

It is a "Low" severity described here.

Steps to reproduce

  1. Load any Drupal page
  2. View the source of the page
  3. Observe script tags for javascript files that reveal the version of the file as "?v=nn.nn"

Proposed resolution

This version identification is baked into core's JsCollectionRenderer::render(). The current approach makes it easy to debug as well as making sure that versions get locally cached appropriately with minimal extra bandwidth needed for unnecessary downloads. We could hash the version to make it undisclosed but still prevent unnecessary downloads.
The end result would have them looking something like this

  <script src="/core/assets/vendor/jquery/jquery.min.js?hv=Myta2hC-FBUCSqirpFCfJxVKMoWwwV4pbwJkSHIpqhM"></script>
  <script src="/core/assets/vendor/underscore/underscore-min.js?hv=OoQsK9DvUuZCnXBLBXAheR1h7N_tK646SIuF4Mf2nQ8"></script>
  <script src="/core/assets/vendor/once/once.min.js?hv=1R5uyUBYVUqEVYpbQC7m71_fVFXjXJAv7aYc2odSlDo"></script>

This change may not ever be something that gets merged to core, but could live as a patch here for those of us that need to prevent version disclosure.

Remaining tasks

User interface changes

None

Introduced terminology

API changes

None

Data model changes

The query parameter v for 'version' would be come hv for 'hashed version'.

Release notes snippet

โœจ Feature request
Status

Active

Version

11.1 ๐Ÿ”ฅ

Component

asset library system

Created by

๐Ÿ‡บ๐Ÿ‡ธUnited States swirt Florida

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @swirt
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States swirt Florida
  • Pipeline finished with Failed
    30 days ago
    Total: 762s
    #469761
  • Pipeline finished with Failed
    30 days ago
    Total: 650s
    #469763
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States swirt Florida

    If there is interest in this actually being merged, let me know and I will rework the failing asset tests to account for this change.

  • ๐Ÿ‡ณ๐Ÿ‡ฟNew Zealand quietone
  • I don't see version numbers on assets with or without aggregation enabled.

  • Yes, they are there on the JavaScript files if aggregation is off. Why is aggregation off on the site?

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States swirt Florida

    @cliefen Good question. Two different answers:

    1. Even with javascript aggregation enabled, when you hit update.php or install.php, it seems they do not use aggregation and the individual script tags are present, which is where the versions are visible.
    2. We have aggregation enabled on our stage an prod environments, so on all pages other than update.php or install.php it is not a full problem there. However we do have aggregation off on our dev environment so that is easier to debug js issues. And on our gov't projects all three environments are scanned due to Zero Trust mindset.

    It is nice that aggregations solves it for most requests, and the Drupal recommended approach is to use aggregation, I don't think it should be a security requirement. There is nothing on the performance UI that says "use JS aggregation or your site will be more at risk."

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States swirt Florida

    I updated the steps to reproduce to be more specific about when and where they are exposed.

  • Heads up - a move in the opposite direction is being asked for in ๐Ÿ“Œ Use library version as query strings for external css (like js does) Active .

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States swirt Florida

    LOL. Interesting. I don't think that would security risk though as CSS rarely has exploitable issues. At least not that I am aware of. :shrug:

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States swirt Florida
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom catch

    I think the scanner here is unreasonable, especially when talking about a dev site in a development mode, but also it would be easy and still correct to use a hash here. Should probably be the very shortest xxhash available.

  • @swirt if you had a situation with Bootstrap, for example, seeing its CSS version would reveal its JS version. Thatโ€™s all on the assumption that this is a security improvement which Iโ€™m doubtful about. In fact, donโ€™t these libraries declare their versions within their code, defeating this proposed protection?

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States swirt Florida

    @cliefen, These are all good questions, and I do not pretend to be a security expert but my current thinking on it is this:

    Thatโ€™s all on the assumption that this is a security improvement which Iโ€™m doubtful about.

    Version disclosure is labeled as a low risk but is serious enough that Drupal does not reveal its minor version, Only the major.

    <meta name="generator" content="Drupal 7 (https://www.drupal.org)" />
    
    <meta name="Generator" content="Drupal 10 (https://www.drupal.org)" />
    

    If it is serious enough that Drupal does not reveal itself, then Drupal should probably show the same level of care to libraries and not reveal their specific version.

    In fact, donโ€™t these libraries declare their versions within their code, defeating this proposed protection?

    Many do. Example: jQuery.fn.jQuery will reveal its own version. If the library wants to reveal its own version, that is the library's choice. However, I think that should remain the choice of the library's maintainers. Drupal should not be the library's loose lipped friend that blabs the secret. I think this falls into the same reason why we routinely make the composer.lock and composer.json of our sites return an access denied.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States swirt Florida

    @catch I took your suggestion on this MR and made it use a shorter hash https://git.drupalcode.org/project/drupal/-/merge_requests/11787

  • Pipeline finished with Failed
    25 days ago
    Total: 545s
    #473191
  • DAST tools and bad actors could additionally hash file contents and compare that against widely published lists to know an asset version. So, no, it actually wouldn't matter whether or not a given library includes its version in code. Anyone can still determine the version. I just want to be clear about how much this change actually would accomplish.

    But, just to be clear, if a fast hash algo gets the job done, I don't see any reason not to do this.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States swirt Florida

    Yes, makes sense. This alone does very little. But does a little. I will work on fixing the failing tests to get this completed.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States swirt Florida
Production build 0.71.5 2024