CVE-2019-1010200 (JavaScript, published 2019-07-23T18:15Z)
Description: value: Voice Builder Prior to commit c145d4604df67e6fc625992412eef0bf9a85e26b and f6660e6d8f0d1d931359d591dbdec580fef36d36 is affected by: CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection'). The impact is: Remote code execution with the same privileges as the servers. The component is: Two web servers in the projects expose three vulnerable endpoints that can be accessed remotely. The endpoints are defined at: - /tts: https://github.com/google/voice-builder/blob/3a449a3e8d5100ff323161c89b897f6d5ccdb6f9/merlin_model_server/api.js#L34 - /alignment: https://github.com/google/voice-builder/blob/3a449a3e8d5100ff323161c89b897f6d5ccdb6f9/festival_model_server/api.js#L28 - /tts: https://github.com/google/voice-builder/blob/3a449a3e8d5100ff323161c89b897f6d5ccdb6f9/festival_model_server/api.js#L65. The attack vector is: Attacker sends a GET request to the vulnerable endpoint with a specially formatted query parameter. The fixed version is: After commit f6660e6d8f0d1d931359d591dbdec580fef36d36.
Severity: HIGH (CVSS v3 base score: 9.8)
Weakness: CWE-78 \u2014 Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.
Repository: https://github.com/google/voice-builder
Files changed:
merlin_model_server/api.js
merlin_model_server/jasmine.json
merlin_model_server/settings.js
merlin_model_server/tests/UtilsTests.js
merlin_model_server/utils.js
Commit message: Added function to replace characters with space and use it to sanitize text

Change-Id: I3d14230444fefa0ce739c498eee6d100bcfe276a


Vulnerable code:
  // TODO(twattanavekin): Test Unicode text.
  const escapedText = JSON.stringify(text).slice(1, -1);
  // Example command:
  //  echo "hello" | ${SYNTH_SCRIPT}

  const cmd = `echo "${escapedText}" | ${SYNTH_SCRIPT}`;
  console.log(`Running command - \n${cmd}`);
  exec(cmd, options, (err, stdout, stderr) => {
  "spec_files": [],

Fixed code:
  const sanitizedText = utils.replaceCharactersWithSpaces(text);
  console.log(`Synthesizing ${sanitizedText}`);
  const child = exec(SYNTH_SCRIPT, options, (err, stdout, stderr) => {
  child.stdin.write(sanitizedText);
  child.stdin.end();
  "spec_files": [
    "UtilsTests.js"
  ],
// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * Module containing settings for merlin server.
 */
const settings = {
  // Merlin synthesis pipeline might not handle these characters as expected
  // and also they are typically not needed during tts synthesis.
  // Therefore we replace them with spaces.
  CHARACTERS_TO_REPLACE_WITH_SPACES: '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~',
};
module.exports = settings;
// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

const utils = require('../utils');

describe('Testing utils replaceCharactersWithSpaces method', () => {
  it('The function should return characters replaced with spaces and trim', () => {
    const testData = [
      ['`<text>`', 'text'],
      ['`text`', 'text'],
      ['$(text)', 'text'],
      ['"\$(text\)', 'text'],
      ['\"\$(text\)', 'text'],
      ['${{{text}', 'text'],
      ['\$\{text\}', 'text'],
      ['\${text"}', 'text'],
      ['"${{text"}', 'text'],
      ['"${text"}', 'text'],
      ["\"ශ්රී ලංකාව'\"", 'ශ්රී ලංකාව'],
      ['"$text"', 'text'],
      ['$text', 'text'],
      [",./;'[]*\-=", ''],
      ['echo `<text>`', 'echo   text'],
      ['echo $("text")', 'echo    text'],
      ['echo \$\{text\}', 'echo   text'],
    ];

    testData.forEach(function(entry) {
      expect(utils.replaceCharactersWithSpaces(entry[0])).toEqual(entry[1]);
    });
  });
});
const settings = require('./settings');

/**
 * Returns the original string with characters
 * specified in settings replaced with spaces.
 * @text {String} text to be replaced.
 */
const replaceCharactersWithSpaces = (text) => {
  const re = new RegExp(`[${settings.CHARACTERS_TO_REPLACE_WITH_SPACES}]`, 'g');
  const newText = text.replace(re, ' ').trim();
  return newText;
};
  replaceCharactersWithSpaces,