Vulnerabilities in pkg:npm/moment-timezone

PACKAGE
Advisory Summary

GHSA-56x4-j7p9-fcf9 is a LOW command injection vulnerability (General Security Weakness) affecting Moment timezone libraries in the npm ecosystem. The issue involves command injection in moment-timezone. Remediation is available by upgrading affected packages to version 0.5.35.

2 Known Advisory Record(s)
Package Vulnerability Intelligence

pkg:npm/moment-timezone

2 Known Advisory Record(s)

Vulnerability advisories affecting package pkg:npm/moment-timezone. Select an advisory below to view technical details or fixes.

Advisory ID CVE / NVD Severity Summary
GHSA-56x4-j7p9-fcf9 - LOW Command Injection in moment-timezone
GHSA-v78c-4p63-2j6c - MODERATE Cleartext Transmission of Sensitive Information in moment-timezone

GHSA-56x4-j7p9-fcf9 at a Glance

CVE Identifier N/A
GHSA Identifier GHSA-56x4-j7p9-fcf9
Severity LOW
CVSS v3.1 Base Score N/A
CWE Classification General Security Weakness
Affected Product Moment timezone
Package Ecosystem npm
Published Date
Last Updated

How to Fix GHSA-56x4-j7p9-fcf9

To remediate this vulnerability, upgrade all affected Moment timezone dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

moment-timezone fixed: 0.5.35
npm install moment-timezone@0.5.35
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

npm ls moment-timezone

How to Check if You Are Affected

To determine whether your Node.js application is affected by GHSA-56x4-j7p9-fcf9, inspect your project dependencies using npm:

npm ls moment-timezone

Analyze the terminal output to locate any version of Moment timezone in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.5.35), your application is affected.

Note: The npm ls moment-timezone command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under General Security Weakness. In Moment timezone, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Impact All versions of moment-timezone from 0.1.0 contain build tasks vulnerable to command injection. * if Alice uses tzdata pipeline to package moment-timezone on her own (for example via `grunt data:2014d`, where `2014d` stands for the version of the tzdata to be used from IANA's website), * and Alice let's Mallory select the version (`2014d` in our example), then Mallory can execute arbitrary commands on the machine running the grunt task, with the same privilege as the grunt task #### Am I affected? ##### Do you build custom versions of moment-timezone with grunt? If no, you're not affected. ##### Do you allow a third party to specify which particular version you want build? If yes, you're vulnerable to command injection -- third party may execute arbitrary commands on the system running grunt task with the same privileges as grunt task. ### Description #### Command Injection via grunt-zdownload.js and MITM on iana's ftp endpoint The `tasks/data-download.js` script takes in a parameter from grunt and uses it to form a command line which is then executed: ``` 6 module.exports = function (grunt) { 7 grunt.registerTask('data-download', '1. Download data from iana.org/time-zones.', function (version) { 8 version = version || 'latest'; 10 var done = this.async(), 11 src = 'ftp://ftp.iana.org/tz/tzdata-latest.tar.gz', 12 curl = path.resolve('temp/curl', version, 'data.tar.gz'), 13 dest = path.resolve('temp/download', version); ... 24 exec('curl ' + src + ' -o ' + curl + ' && cd ' + dest + ' && gzip -dc ' + curl + ' | tar -xf -', function (err) { ``` Ordinarily, one one run this script using something like `grunt data-download:2014d`, in which case version would have the value `2014d`. However, if an attacker were to provide additional content on the command line, they would be able to execute arbitrary code ``` root@e94ba0490b65:/usr/src/app/moment-timezone# grunt 'data-download:2014d ; echo flag>/tmp/foo #' \Running "data-download:2014d ; echo flag>/tmp/foo #" (data-download) task >> Downloading https://data.iana.org/time-zones/releases/tzdata2014d ; echo flag>/tmp/foo #.tar.gz >> Downloaded https://data.iana.org/time-zones/releases/tzdata2014d ; echo flag>/tmp/foo #.tar.gz Done. root@e94ba0490b65:/usr/src/app/moment-timezone# cat /tmp/foo flag ``` #### Command Injection via data-zdump.js The `tasks/data-zdump.js` script reads a list of files present in a temporary directory (created by previous tasks), and for each one, assembles and executes a command line without sanitization. As a result, an attacker able to influence the contents of that directory could gain code execution. This attack is exacerbated by timezone data being downloaded via cleartext FTP (described above), but beyond that, an attacker at iana.org able to modify the timezone files could disrupt any systems that build moment-timezone. ``` 15 files = grunt.file.expand({ filter : 'isFile', cwd : 'temp/zic/' + version }, '**/*'); ... 27 function next () { ... 33 var file = files.pop(), 34 src = path.join(zicBase, file), 35 dest = path.join(zdumpBase, file); 36 exec('zdump -v ' + src, { maxBuffer: 20*1024*1024 }, function (err, stdout) { ``` In this case, an attacker able to add a file to `temp/zic/2014d` (for example) with a filename like `Z; curl www.example.com` would influence the called to exec on line 36 and run arbitrary code. There are a few minor challenges in exploiting this, since the string needs to be a valid filename. #### Command Injection via data-zic.js Similar to the vulnerability in /tasks/data-download.js, the /tasks/data-zic.js script takes a version from the command line and uses it as part of a command line, executed without sanitization. ``` 10 var done = this.async(), 11 dest = path.resolve('temp/zic', version), ... 22 var file = files.shift(), 23 src = path.resolve('temp/download', version, file); 24 25 exec('zic -d ' + dest + ' ' + src, function (err) { ``` As a result, an attacker able to influence that string can run arbitrary commands. Of course, it requires an attacker able to influence the command passed to grunt, so may be unlikely in practice. ``` root@e94ba0490b65:/usr/src/app/moment-timezone# grunt 'data-zic:2014d; echo hi > /tmp/evil; echo ' Running "data-zic:2014d; echo hi > /tmp/evil; echo " (data-zic) task exec: zid -d /usr/src/app/moment-timezone/temp/zic/2014d; echo hi > /tmp/evil; echo /usr/src/app/moment-timezone/temp/download/2014d; echo hi > /tmp/evil; echo /africa ... root@e94ba0490b65:/usr/src/app/moment-timezone# cat /tmp/evil hi ``` ### Patches The supplied patch on top of 0.5.34 is applicable with minor tweaks to all affected versions. It switches `exec` to `execFile` so arbitrary bash fragments won't be executed any more. ### References * https://knowledge-base.secureflag.com/vulnerabilities/code_injection/os_command_injection_nodejs.html * https://auth0.com/blog/preventing-command-injection-attacks-in-node-js-apps/

GHSA-56x4-j7p9-fcf9 Affected Moment timezone Versions

1 component(s)
Fixed Versions:
0.5.35
Product / Package Ecosystem Affected Versions Fixed Version
moment-timezone
npm
≥ 0.1.0
< 0.5.35
0.5.35

References

Frequently Asked Questions

What is GHSA-56x4-j7p9-fcf9?
GHSA-56x4-j7p9-fcf9 is a security vulnerability in Moment timezone involving Command Injection in moment-timezone under General Security Weakness.
Which Moment timezone versions are affected?
Affected versions include releases prior to 0.5.35 across affected packages: moment-timezone.
What version fixes GHSA-56x4-j7p9-fcf9?
Upgrading to 0.5.35 (or the latest patched release for your respective branch) resolves the vulnerability.
Is moment-timezone affected?
Yes, moment-timezone is affected in releases prior to 0.5.35. Upgrade your dependency to 0.5.35 or later.
What CWE is associated with GHSA-56x4-j7p9-fcf9?
GHSA-56x4-j7p9-fcf9 is classified under General Security Weakness.
How can I check npm dependencies for GHSA-56x4-j7p9-fcf9?
Run the dependency tree command: 'npm ls moment-timezone'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-56x4-j7p9-fcf9",
  "modified" : "2022-08-30T20:31:21Z",
  "published" : "2022-08-30T20:31:21Z",
  "aliases" : [ ],
  "summary" : "Command Injection in moment-timezone",
  "details" : "### Impact\n\nAll versions of moment-timezone from 0.1.0 contain build tasks vulnerable to command injection.\n\n* if Alice uses tzdata pipeline to package moment-timezone on her own (for example via `grunt data:2014d`, where `2014d` stands for the version of the tzdata to be used from IANA's website),\n* and Alice let's Mallory select the version (`2014d` in our example), then Mallory can execute arbitrary commands on the machine running the grunt task, with the same privilege as the grunt task\n\n#### Am I affected?\n\n##### Do you build custom versions of moment-timezone with grunt?\n\nIf no, you're not affected.\n\n##### Do you allow a third party to specify which particular version you want build?\n\nIf yes, you're vulnerable to command injection -- third party may execute arbitrary commands on the system running grunt task with the same privileges as grunt task.\n\n### Description\n\n#### Command Injection via grunt-zdownload.js and MITM on iana's ftp endpoint\n\nThe `tasks/data-download.js` script takes in a parameter from grunt and uses it to form a command line which is then executed:\n\n```\n6  module.exports = function (grunt) {\n7      grunt.registerTask('data-download', '1. Download data from iana.org/time-zones.', function (version) {\n8          version = version || 'latest';\n\n10          var done  = this.async(),\n11              src   = 'ftp://ftp.iana.org/tz/tzdata-latest.tar.gz',\n12              curl  = path.resolve('temp/curl', version, 'data.tar.gz'),\n13              dest  = path.resolve('temp/download', version);\n...\n24          exec('curl ' + src + ' -o ' + curl + ' && cd ' + dest + ' && gzip -dc ' + curl + ' | tar -xf -', function (err) {\n```\n\nOrdinarily, one one run this script using something like `grunt data-download:2014d`, in which case version would have the value `2014d`. However, if an attacker were to provide additional content on the command line, they would be able to execute arbitrary code\n\n```\nroot@e94ba0490b65:/usr/src/app/moment-timezone# grunt 'data-download:2014d ; echo flag>/tmp/foo #'\n\\Running \"data-download:2014d ; echo flag>/tmp/foo #\" (data-download) task\n>> Downloading https://data.iana.org/time-zones/releases/tzdata2014d ; echo flag>/tmp/foo #.tar.gz\n>> Downloaded https://data.iana.org/time-zones/releases/tzdata2014d ; echo flag>/tmp/foo #.tar.gz\n\nDone.\nroot@e94ba0490b65:/usr/src/app/moment-timezone# cat /tmp/foo\nflag\n```\n\n#### Command Injection via data-zdump.js\n\nThe `tasks/data-zdump.js` script reads a list of files present in a temporary directory (created by previous tasks), and for each one, assembles and executes a command line without sanitization. As a result, an attacker able to influence the contents of that directory could gain code execution. This attack is exacerbated by timezone data being downloaded via cleartext FTP (described above), but beyond that, an attacker at iana.org able to modify the timezone files could disrupt any systems that build moment-timezone.\n\n```\n15              files     = grunt.file.expand({ filter : 'isFile', cwd : 'temp/zic/' + version }, '**/*');\n...\n27          function next () {\n...\n33              var file = files.pop(),\n34                  src  = path.join(zicBase, file),\n35                  dest = path.join(zdumpBase, file);\n36              exec('zdump -v ' + src, { maxBuffer: 20*1024*1024 }, function (err, stdout) {\n```\n\nIn this case, an attacker able to add a file to `temp/zic/2014d` (for example) with a filename like `Z; curl www.example.com` would influence the called to exec on line 36 and run arbitrary code. There are a few minor challenges in exploiting this, since the string needs to be a valid filename.\n\n#### Command Injection via data-zic.js\n\nSimilar to the vulnerability in /tasks/data-download.js, the /tasks/data-zic.js script takes a version from the command line and uses it as part of a command line, executed without sanitization.\n\n```\n10          var done  = this.async(),\n11              dest  = path.resolve('temp/zic', version),\n...\n22              var file = files.shift(),\n23                  src = path.resolve('temp/download', version, file);\n24\n25              exec('zic -d ' + dest + ' ' + src, function (err) {\n```\n\nAs a result, an attacker able to influence that string can run arbitrary commands. Of course, it requires an attacker able to influence the command passed to grunt, so may be unlikely in practice.\n\n```\nroot@e94ba0490b65:/usr/src/app/moment-timezone# grunt 'data-zic:2014d; echo hi > /tmp/evil; echo '\nRunning \"data-zic:2014d; echo hi > /tmp/evil; echo \" (data-zic) task\nexec: zid -d /usr/src/app/moment-timezone/temp/zic/2014d; echo hi > /tmp/evil; echo  /usr/src/app/moment-timezone/temp/download/2014d; echo hi > /tmp/evil; echo /africa\n...\n\nroot@e94ba0490b65:/usr/src/app/moment-timezone# cat /tmp/evil\nhi\n```\n\n### Patches\n\nThe supplied patch on top of 0.5.34 is applicable with minor tweaks to all affected versions. It switches `exec` to `execFile` so arbitrary bash fragments won't be executed any more.\n\n### References\n\n* https://knowledge-base.secureflag.com/vulnerabilities/code_injection/os_command_injection_nodejs.html\n* https://auth0.com/blog/preventing-command-injection-attacks-in-node-js-apps/",
  "severity" : [ ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "npm",
      "name" : "moment-timezone"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0.1.0"
      }, {
        "fixed" : "0.5.35"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/moment/moment-timezone/security/advisories/GHSA-56x4-j7p9-fcf9"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/moment/moment-timezone/commit/ce955a301ff372e8e9fb3a5b516620c60e7a082a"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/moment/moment-timezone"
  } ],
  "database_specific" : {
    "cwe_ids" : [ ],
    "severity" : "LOW",
    "github_reviewed" : true,
    "github_reviewed_at" : "2022-08-30T20:31:21Z",
    "nvd_published_at" : null
  }
}