All the vulnerabilities related to the version 3.16.0 of the package
ggit is vulnerable to Command Injection via the fetchTags(branch) API
All versions of the package ggit are vulnerable to Command Injection via the fetchTags(branch) API, which allows user input to specify the branch to be fetched and then concatenates this string along with a git command which is then passed to the unsafe exec() Node.js child process API.
ggit is vulnerable to Arbitrary Argument Injection via the clone() API
All versions of the package ggit are vulnerable to Arbitrary Argument Injection via the clone() API, which allows specifying the remote URL to clone and the file on disk to clone to. The library does not sanitize for user input or validate a given URL scheme, nor does it properly pass command-line flags to the git binary using the double-dash POSIX characters (--) to communicate the end of options.
Prototype Pollution in lodash
Versions of lodash
before 4.17.5 are vulnerable to prototype pollution.
The vulnerable functions are 'defaultsDeep', 'merge', and 'mergeWith' which allow a malicious user to modify the prototype of Object
via __proto__
causing the addition or modification of an existing property that will exist on all objects.
Update to version 4.17.5 or later.
Prototype Pollution in lodash
Versions of lodash
before 4.17.11 are vulnerable to prototype pollution.
The vulnerable functions are 'defaultsDeep', 'merge', and 'mergeWith' which allow a malicious user to modify the prototype of Object
via {constructor: {prototype: {...}}}
causing the addition or modification of an existing property that will exist on all objects.
Update to version 4.17.11 or later.
Regular Expression Denial of Service (ReDoS) in lodash
lodash prior to 4.7.11 is affected by: CWE-400: Uncontrolled Resource Consumption. The impact is: Denial of service. The component is: Date handler. The attack vector is: Attacker provides very long strings, which the library attempts to match using a regular expression. The fixed version is: 4.7.11.
Prototype Pollution in lodash
Versions of lodash
before 4.17.12 are vulnerable to Prototype Pollution. The function defaultsDeep
allows a malicious user to modify the prototype of Object
via {constructor: {prototype: {...}}}
causing the addition or modification of an existing property that will exist on all objects.
Update to version 4.17.12 or later.
Prototype Pollution in lodash
Versions of lodash prior to 4.17.19 are vulnerable to Prototype Pollution. The functions pick
, set
, setWith
, update
, updateWith
, and zipObjectDeep
allow a malicious user to modify the prototype of Object if the property identifiers are user-supplied. Being affected by this issue requires manipulating objects based on user-provided property values or arrays.
This vulnerability causes the addition or modification of an existing property that will exist on all objects and may lead to Denial of Service or Code Execution under specific circumstances.
Regular Expression Denial of Service (ReDoS) in lodash
All versions of package lodash prior to 4.17.21 are vulnerable to Regular Expression Denial of Service (ReDoS) via the toNumber
, trim
and trimEnd
functions.
Steps to reproduce (provided by reporter Liyuan Chen):
var lo = require('lodash');
function build_blank(n) {
var ret = "1"
for (var i = 0; i < n; i++) {
ret += " "
}
return ret + "1";
}
var s = build_blank(50000) var time0 = Date.now();
lo.trim(s)
var time_cost0 = Date.now() - time0;
console.log("time_cost0: " + time_cost0);
var time1 = Date.now();
lo.toNumber(s) var time_cost1 = Date.now() - time1;
console.log("time_cost1: " + time_cost1);
var time2 = Date.now();
lo.trimEnd(s);
var time_cost2 = Date.now() - time2;
console.log("time_cost2: " + time_cost2);
Command Injection in lodash
lodash
versions prior to 4.17.21 are vulnerable to Command Injection via the template function.
Regular Expression Denial of Service in moment
Affected versions of moment
are vulnerable to a low severity regular expression denial of service when parsing dates as strings.
Update to version 2.19.3 or later.
Path Traversal: 'dir/../../filename' in moment.locale
This vulnerability impacts npm (server) users of moment.js, especially if user provided locale string, eg fr
is directly used to switch moment locale.
This problem is patched in 2.29.2, and the patch can be applied to all affected versions (from 1.0.1 up until 2.29.1, inclusive).
Sanitize user-provided locale name before passing it to moment.js.
Are there any links users can visit to find out more?
If you have any questions or comments about this advisory:
Moment.js vulnerable to Inefficient Regular Expression Complexity
The problem is patched in 2.29.4, the patch can be applied to all affected versions with minimal tweaking.
In general, given the proliferation of ReDoS attacks, it makes sense to limit the length of the user input to something sane, like 200 characters or less. I haven't seen legitimate cases of date-time strings longer than that, so all moment users who do pass a user-originating string to constructor are encouraged to apply such a rudimentary filter, that would help with this but also most future ReDoS vulnerabilities.
There is an excellent writeup of the issue here: https://github.com/moment/moment/pull/6015#issuecomment-1152961973=
The issue is rooted in the code that removes legacy comments (stuff inside parenthesis) from strings during rfc2822 parsing. moment("(".repeat(500000))
will take a few minutes to process, which is unacceptable.
Command Injection in moment-timezone
All versions of moment-timezone from 0.1.0 contain build tasks vulnerable to command injection.
grunt data:2014d
, where 2014d
stands for the version of the tzdata to be used from IANA's website),2014d
in our example), then Mallory can execute arbitrary commands on the machine running the grunt task, with the same privilege as the grunt taskIf no, you're not affected.
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.
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
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.
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
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.
Cleartext Transmission of Sensitive Information in moment-timezone
grunt data
(or grunt release
) to prepare a custom-build, moment-timezone with the latest tzdata from IANA's websiteProblem has been patched in version 0.5.35, patch should be applicable with minor modifications to all affected versions. The patch includes changing the FTP endpoint with an HTTPS endpoint.
Specify the exact version of tzdata (like 2014d
, full command being grunt data:2014d
, then run the rest of the release tasks by hand), or just apply the patch before issuing the grunt command.
Prototype Pollution in minimist
Affected versions of minimist
are vulnerable to prototype pollution. Arguments are not properly sanitized, allowing an attacker to modify the prototype of Object
, causing the addition or modification of an existing property that will exist on all objects.
Parsing the argument --__proto__.y=Polluted
adds a y
property with value Polluted
to all objects. The argument --__proto__=Polluted
raises and uncaught error and crashes the application.
This is exploitable if attackers have control over the arguments being passed to minimist
.
Upgrade to versions 0.2.1, 1.2.3 or later.
Prototype Pollution in minimist
Minimist prior to 1.2.6 and 0.2.4 is vulnerable to Prototype Pollution via file index.js
, function setKey()
(lines 69-95).
semver vulnerable to Regular Expression Denial of Service
Versions of the package semver before 7.5.2 on the 7.x branch, before 6.3.1 on the 6.x branch, and all other versions before 5.7.2 are vulnerable to Regular Expression Denial of Service (ReDoS) via the function new Range, when untrusted user data is provided as a range.
tmp allows arbitrary temporary file / directory write via symbolic link dir
parameter
tmp@0.2.3
is vulnerable to an Arbitrary temporary file / directory write via symbolic link dir
parameter.
According to the documentation there are some conditions that must be held:
// https://github.com/raszi/node-tmp/blob/v0.2.3/README.md?plain=1#L41-L50
Other breaking changes, i.e.
- template must be relative to tmpdir
- name must be relative to tmpdir
- dir option must be relative to tmpdir //<-- this assumption can be bypassed using symlinks
are still in place.
In order to override the system's tmpdir, you will have to use the newly
introduced tmpdir option.
// https://github.com/raszi/node-tmp/blob/v0.2.3/README.md?plain=1#L375
* `dir`: the optional temporary directory that must be relative to the system's default temporary directory.
absolute paths are fine as long as they point to a location under the system's default temporary directory.
Any directories along the so specified path must exist, otherwise a ENOENT error will be thrown upon access,
as tmp will not check the availability of the path, nor will it establish the requested path for you.
Related issue: https://github.com/raszi/node-tmp/issues/207.
The issue occurs because _resolvePath
does not properly handle symbolic link when resolving paths:
// https://github.com/raszi/node-tmp/blob/v0.2.3/lib/tmp.js#L573-L579
function _resolvePath(name, tmpDir) {
if (name.startsWith(tmpDir)) {
return path.resolve(name);
} else {
return path.resolve(path.join(tmpDir, name));
}
}
If the dir
parameter points to a symlink that resolves to a folder outside the tmpDir
, it's possible to bypass the _assertIsRelative
check used in _assertAndSanitizeOptions
:
// https://github.com/raszi/node-tmp/blob/v0.2.3/lib/tmp.js#L590-L609
function _assertIsRelative(name, option, tmpDir) {
if (option === 'name') {
// assert that name is not absolute and does not contain a path
if (path.isAbsolute(name))
throw new Error(`${option} option must not contain an absolute path, found "${name}".`);
// must not fail on valid .<name> or ..<name> or similar such constructs
let basename = path.basename(name);
if (basename === '..' || basename === '.' || basename !== name)
throw new Error(`${option} option must not contain a path, found "${name}".`);
}
else { // if (option === 'dir' || option === 'template') {
// assert that dir or template are relative to tmpDir
if (path.isAbsolute(name) && !name.startsWith(tmpDir)) {
throw new Error(`${option} option must be relative to "${tmpDir}", found "${name}".`);
}
let resolvedPath = _resolvePath(name, tmpDir); //<---
if (!resolvedPath.startsWith(tmpDir))
throw new Error(`${option} option must be relative to "${tmpDir}", found "${resolvedPath}".`);
}
}
The following PoC demonstrates how writing a tmp file on a folder outside the tmpDir
is possible.
Tested on a Linux machine.
tmpDir
that points to a directory outside of itmkdir $HOME/mydir1
ln -s $HOME/mydir1 ${TMPDIR:-/tmp}/evil-dir
ls -lha $HOME/mydir1 | grep "tmp-"
node main.js
File: /tmp/evil-dir/tmp-26821-Vw87SLRaBIlf
test 1: ENOENT: no such file or directory, open '/tmp/mydir1/tmp-[random-id]'
test 2: dir option must be relative to "/tmp", found "/foo".
test 3: dir option must be relative to "/tmp", found "/home/user/mydir1".
$HOME/mydir1
(outside the tmpDir
):ls -lha $HOME/mydir1 | grep "tmp-"
-rw------- 1 user user 0 Apr X XX:XX tmp-[random-id]
main.js
// npm i tmp@0.2.3
const tmp = require('tmp');
const tmpobj = tmp.fileSync({ 'dir': 'evil-dir'});
console.log('File: ', tmpobj.name);
try {
tmp.fileSync({ 'dir': 'mydir1'});
} catch (err) {
console.log('test 1:', err.message)
}
try {
tmp.fileSync({ 'dir': '/foo'});
} catch (err) {
console.log('test 2:', err.message)
}
try {
const fs = require('node:fs');
const resolved = fs.realpathSync('/tmp/evil-dir');
tmp.fileSync({ 'dir': resolved});
} catch (err) {
console.log('test 3:', err.message)
}
A Potential fix could be to call fs.realpathSync
(or similar) that resolves also symbolic links.
function _resolvePath(name, tmpDir) {
let resolvedPath;
if (name.startsWith(tmpDir)) {
resolvedPath = path.resolve(name);
} else {
resolvedPath = path.resolve(path.join(tmpDir, name));
}
return fs.realpathSync(resolvedPath);
}
Arbitrary temporary file / directory write via symlink
Improper Privilege Management in shelljs
shelljs is vulnerable to Improper Privilege Management
Improper Privilege Management in shelljs
Output from the synchronous version of shell.exec()
may be visible to other users on the same system. You may be affected if you execute shell.exec()
in multi-user Mac, Linux, or WSL environments, or if you execute shell.exec()
as the root user.
Other shelljs functions (including the asynchronous version of shell.exec()
) are not impacted.
Patched in shelljs 0.8.5
Recommended action is to upgrade to 0.8.5.
https://huntr.dev/bounties/50996581-c08e-4eed-a90e-c0bac082679c/
If you have any questions or comments about this advisory:
semver-regex Regular Expression Denial of Service (ReDOS)
npm semver-regex
is vulnerable to Inefficient Regular Expression Complexity
Regular expression denial of service in semver-regex
An exponential ReDoS (Regular Expression Denial of Service) can be triggered in the semver-regex npm package, when an attacker is able to supply arbitrary input to the test() method
word-wrap vulnerable to Regular Expression Denial of Service
All versions of the package word-wrap are vulnerable to Regular Expression Denial of Service (ReDoS) due to the usage of an insecure regular expression within the result variable.