From 47d92e96fe02dd23ff503fc7d7ce56accd3316f7 Mon Sep 17 00:00:00 2001 From: Sam Bostock Date: Thu, 20 Feb 2020 02:17:53 -0500 Subject: [PATCH] Escape shell args Passing strings to diff as unescaped shell arguments to printf can result in unexpected (and potentially exploitable) behaviour if the strings contain special characters, such as backticks (`). --- js/gitDiffReal/bugFixes.spec.js | 6 ++++++ js/gitDiffReal/generateDiff/index.js | 8 ++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/js/gitDiffReal/bugFixes.spec.js b/js/gitDiffReal/bugFixes.spec.js index f9e1d70..8566f0f 100644 --- a/js/gitDiffReal/bugFixes.spec.js +++ b/js/gitDiffReal/bugFixes.spec.js @@ -21,5 +21,11 @@ describe('gitDiffReal', function() { var actual = gitDiffReal('', '', {color: false, wordDiff: true}) imp.expect(actual).to.equal(expected) }) + + it('` in string is not interpreted as shell subcommand', function() { + var expected = '@@ -1 +1 @@\n[-`a`b-]{+`c`d+}\n' + var actual = gitDiffReal('`a`b', '`c`d', {color: false, wordDiff: true}) + imp.expect(actual).to.equal(expected) + }) }) }) diff --git a/js/gitDiffReal/generateDiff/index.js b/js/gitDiffReal/generateDiff/index.js index 3f14cd3..3bc6526 100644 --- a/js/gitDiffReal/generateDiff/index.js +++ b/js/gitDiffReal/generateDiff/index.js @@ -12,6 +12,10 @@ logger.setLevel('info') // git diff $(printf 'my first string' | git hash-object -w --stdin) $(printf 'my second string' | git hash-object -w --stdin) --word-diff // git diff $(printf 'This is a test for my diff tool\nIt is a big test\n\nNo diff here\n\nBut there might be here\nBut not here\n\nOr here\n' | git hash-object -w --stdin) $(printf 'This is a test for my difference tool\nIt is a small test\n\nNo diff here\n\nBut there might be here!\nBut not here\n\nOr here\n' | git hash-object -w --stdin) --word-diff +function escapeShellArg(arg) { + return "'" + arg.replace(/'/g, "'\\''") + "'" +} + function generateDiff(str1, str2, options, gitDir) { var DEFAULTS = require('../../_shared/defaultOptions') @@ -23,8 +27,8 @@ function generateDiff(str1, str2, options, gitDir) { } // Single quotes is needed here to avoid .. event not found - var gitHashCmd1 = 'printf ' + JSON.stringify(str1) + ' | git ' + gitDir + ' hash-object -w --stdin' - var gitHashCmd2 = 'printf ' + JSON.stringify(str2) + ' | git ' + gitDir + ' hash-object -w --stdin' + var gitHashCmd1 = 'printf ' + escapeShellArg(str1) + ' | git ' + gitDir + ' hash-object -w --stdin' + var gitHashCmd2 = 'printf ' + escapeShellArg(str2) + ' | git ' + gitDir + ' hash-object -w --stdin' var gitHashObj1 = exec(gitHashCmd1, {silent: true}) var gitHashObj2 = exec(gitHashCmd2, {silent: true})