1'use strict'; 2const common = require('../common'); 3if (process.platform !== 'darwin') 4 common.skip('App Sandbox is only available on Darwin'); 5if (process.config.variables.node_builtin_modules_path) 6 common.skip('App Sandbox cannot load modules from outside the sandbox'); 7 8const fixtures = require('../common/fixtures'); 9const tmpdir = require('../common/tmpdir'); 10const assert = require('assert'); 11const child_process = require('child_process'); 12const path = require('path'); 13const fs = require('fs'); 14const os = require('os'); 15 16const nodeBinary = process.execPath; 17 18tmpdir.refresh(); 19 20const appBundlePath = path.join(tmpdir.path, 'node_sandboxed.app'); 21const appBundleContentPath = path.join(appBundlePath, 'Contents'); 22const appExecutablePath = path.join( 23 appBundleContentPath, 'MacOS', 'node'); 24 25// Construct the app bundle and put the node executable in it: 26// node_sandboxed.app/ 27// └── Contents 28// ├── Info.plist 29// ├── MacOS 30// │ └── node 31fs.mkdirSync(appBundlePath); 32fs.mkdirSync(appBundleContentPath); 33fs.mkdirSync(path.join(appBundleContentPath, 'MacOS')); 34fs.copyFileSync( 35 fixtures.path('macos-app-sandbox', 'Info.plist'), 36 path.join(appBundleContentPath, 'Info.plist')); 37fs.copyFileSync( 38 nodeBinary, 39 appExecutablePath); 40 41 42// Sign the app bundle with sandbox entitlements: 43assert.strictEqual( 44 child_process.spawnSync('/usr/bin/codesign', [ 45 '--entitlements', fixtures.path( 46 'macos-app-sandbox', 'node_sandboxed.entitlements'), 47 '--force', '-s', '-', 48 appBundlePath, 49 ]).status, 50 0); 51 52// Sandboxed app shouldn't be able to read the home dir 53assert.notStrictEqual( 54 child_process.spawnSync(appExecutablePath, [ 55 '-e', 'fs.readdirSync(process.argv[1])', os.homedir(), 56 ]).status, 57 0); 58 59if (process.stdin.isTTY) { 60 // Run the sandboxed node instance with inherited tty stdin 61 const spawnResult = child_process.spawnSync( 62 appExecutablePath, ['-e', ''], 63 { stdio: 'inherit' } 64 ); 65 66 assert.strictEqual(spawnResult.signal, null); 67} 68