CVE-2020-7729 (published 2020-09-03T09:15Z)

The package grunt before 1.3.0 are vulnerable to Arbitrary Code Execution due to the default usage of the function load() instead of its secure replacement safeLoad() of the package js-yaml inside grunt.file.readYAML.

Severity: MEDIUM
CVSS v2 base score: 4.6 (AV:N/AC:H/Au:S/C:P/I:P/A:P)
CVSS v3 base score: 7.1, HIGH (CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-1188
cwe_name: Initialization of a Resource with an Insecure Default
description: The product initializes or sets a resource with a default that is intended to be changed by the administrator, but the default is not secure.
extended_description: Developers often choose default values that leave the product as open and easy to use as possible out-of-the-box, under the assumption that the administrator can (or should) change the default value.  However, this ease-of-use comes at a cost when the default is insecure and the administrator does not change it.
	 
         

Fix information:
repo_url: https://github.com/gruntjs/grunt
commit_details: repo_url: https://github.com/gruntjs/grunt
author: Vlad Filippov
author_date: 2020-08-17 11:28:59-04:00
msg: Switch to use `safeLoad` for loading YML files via `file.readYAML`.

For previous behaviour please use the following:

```
readYAML('test/fixtures/utf8.yaml', null, {unsafeLoad: true});
```
repository: repo_url: https://github.com/gruntjs/grunt
repo_name: gruntjs/grunt
description: Grunt: The JavaScript Task Runner
repo_language: JavaScript
owner: gruntjs
file_changes: filename: file.js
change_type: ModificationType.MODIFY
diff: @@ -241,12 +241,21 @@ file.readJSON = function(filepath, options) {
 };
 
 // Read a YAML file, parse its contents, return an object.
-file.readYAML = function(filepath, options) {
+file.readYAML = function(filepath, options, yamlOptions) {
+  if (!options) { options = {}; }
+  if (!yamlOptions) { yamlOptions = {}; }
+
   var src = file.read(filepath, options);
   var result;
   grunt.verbose.write('Parsing ' + filepath + '...');
   try {
-    result = YAML.load(src);
+    // use the recommended way of reading YAML files
+    // https://github.com/nodeca/js-yaml#safeload-string---options-
+    if (yamlOptions.unsafeLoad) {
+      result = YAML.load(src);
+    } else {
+      result = YAML.safeLoad(src);
+    }
     grunt.verbose.ok();
     return result;
   } catch (e) {

programming_language: JavaScript
filename: file_test.js
change_type: ModificationType.MODIFY
diff: @@ -452,10 +452,13 @@ exports.file = {
     test.done();
   },
   'readYAML': function(test) {
-    test.expect(4);
+    test.expect(5);
     var obj;
     obj = grunt.file.readYAML('test/fixtures/utf8.yaml');
-    test.deepEqual(obj, this.object, 'file should be read as utf8 by default and parsed correctly.');
+    test.deepEqual(obj, this.object, 'file should be safely read as utf8 by default and parsed correctly.');
+
+    obj = grunt.file.readYAML('test/fixtures/utf8.yaml', null, {unsafeLoad: true});
+    test.deepEqual(obj, this.object, 'file should be unsafely read as utf8 by default and parsed correctly.');
 
     obj = grunt.file.readYAML('test/fixtures/iso-8859-1.yaml', {encoding: 'iso-8859-1'});
     test.deepEqual(obj, this.object, 'file should be read using the specified encoding.');

programming_language: JavaScript