diff --git a/lib/internal/repl.js b/lib/internal/repl.js index 742c9b3419c81c..b72741609ba87e 100644 --- a/lib/internal/repl.js +++ b/lib/internal/repl.js @@ -93,7 +93,10 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) { var writing = false; var pending = false; repl.pause(); - fs.open(historyPath, 'a+', oninit); + // History files are conventionally not readable by others: + // https://github.com/nodejs/node/issues/3392 + // https://github.com/nodejs/node/pull/3394 + fs.open(historyPath, 'a+', 0o0600, oninit); function oninit(err, hnd) { if (err) { diff --git a/test/parallel/test-repl-history-perm.js b/test/parallel/test-repl-history-perm.js new file mode 100644 index 00000000000000..717728bc4fc287 --- /dev/null +++ b/test/parallel/test-repl-history-perm.js @@ -0,0 +1,53 @@ +'use strict'; +// Flags: --expose_internals + +const common = require('../common'); + +if (common.isWindows) { + console.log('1..0 # Skipped: Win32 uses ACLs for file permissions, ' + + 'modes are always 0666 and says nothing about group/other ' + + 'read access.'); + return; +} + +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); +const repl = require('internal/repl'); +const Duplex = require('stream').Duplex; +// Invoking the REPL should create a repl history file at the specified path +// and mode 600. + +var stream = new Duplex(); +stream.pause = stream.resume = function() {}; +// ends immediately +stream._read = function() { + this.push(null); +}; +stream._write = function(c, e, cb) { + cb(); +}; +stream.readable = stream.writable = true; + +common.refreshTmpDir(); +const replHistoryPath = path.join(common.tmpDir, '.node_repl_history'); + +const checkResults = common.mustCall(function(err, r) { + if (err) + throw err; + r.input.end(); + const stat = fs.statSync(replHistoryPath); + assert.strictEqual( + stat.mode & 0o777, 0o600, + 'REPL history file should be mode 0600'); +}); + +repl.createInternalRepl( + {NODE_REPL_HISTORY: replHistoryPath}, + { + terminal: true, + input: stream, + output: stream + }, + checkResults +);