Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix command injection and remove useless util.format #43

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions lib/simctl-extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,14 @@ const fs = require('fs')
const util = require('util')
const Tail = require('tail').Tail

const escapeShellArg = function (arg) {
return typeof arg === 'string' ? arg.replace(/(["`])/g, '\\$1') : arg;
}

const extensions = {
start: function (deviceid) {
deviceid = escapeShellArg(deviceid)

let isAtLeastXcode9 = false

let command = 'xcodebuild -version'
Expand All @@ -46,7 +52,7 @@ const extensions = {

if (isAtLeastXcode9) {
// Xcode 9 or greater
command = util.format('xcrun simctl list -j')
command = `xcrun simctl list -j`
let res = shell.exec(command, { silent: true })
if (res.code !== 0) {
console.error('Could not get device list.')
Expand All @@ -62,7 +68,7 @@ const extensions = {
console.error('Simulator already running.')
return
}
command = util.format('xcrun simctl boot "%s"', deviceid)
command = `xcrun simctl boot "${deviceid}"`
res = shell.exec(command, { silent: true })

if (res.code !== 0) {
Expand All @@ -74,7 +80,7 @@ const extensions = {
return shell.exec(command, { silent: true })
} else {
// Xcode 8 or older
command = util.format('xcrun instruments -w "%s"', deviceid)
command = `xcrun instruments -w "${deviceid}"`
return shell.exec(command, { silent: true })
}
},
Expand Down
45 changes: 23 additions & 22 deletions simctl.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ THE SOFTWARE.
*/

const shell = require('shelljs')
const util = require('util')
const SimCtlExtensions = require('./lib/simctl-extensions')

const escapeShellArg = function (arg) {
return typeof arg === 'string' ? arg.replace(/(["`])/g, '\\$1') : arg;
}

exports = module.exports = {

set noxpc (b) {
Expand All @@ -39,7 +42,7 @@ exports = module.exports = {
extensions: SimCtlExtensions,

check_prerequisites: function () {
const command = util.format('xcrun simctl help')
const command = `xcrun simctl help`
const obj = shell.exec(command, { silent: true })

if (obj.code !== 0) {
Expand All @@ -54,57 +57,57 @@ exports = module.exports = {
},

create: function (name, deviceTypeId, runtimeId) {
const command = util.format('xcrun simctl create "%s" "%s" "%s"', name, deviceTypeId, runtimeId)
const command = `xcrun simctl create "${escapeShellArg(name)}" "${escapeShellArg(deviceTypeId)}" "${escapeShellArg(runtimeId)}"`;
return shell.exec(command)
},

del: function (device) {
const command = util.format('xcrun simctl delete "%s"', device)
const command = `xcrun simctl delete "${escapeShellArg(device)}"`
return shell.exec(command)
},

erase: function (device) {
const command = util.format('xcrun simctl erase "%s"', device)
const command = `xcrun simctl erase "${escapeShellArg(device)}"`
return shell.exec(command)
},

boot: function (device) {
const command = util.format('xcrun simctl boot "%s"', device)
const command = `xcrun simctl boot "${escapeShellArg(device)}"`
return shell.exec(command)
},

shutdown: function (device) {
const command = util.format('xcrun simctl shutdown "%s"', device)
const command = `xcrun simctl shutdown "${escapeShellArg(device)}"`
return shell.exec(command)
},

rename: function (device, name) {
const command = util.format('xcrun simctl rename "%s" "%s"', device, name)
const command = `xcrun simctl rename "${escapeShellArg(device)}" "${escapeShellArg(name)}"`
return shell.exec(command)
},

getenv: function (device, variableName) {
const command = util.format('xcrun simctl getenv "%s" "%s"', device, variableName)
const command = `xcrun simctl getenv "${escapeShellArg(device)}" "${escapeShellArg(variableName)}"`
return shell.exec(command)
},

openurl: function (device, url) {
const command = util.format('xcrun simctl openurl "%s" "%s"', device, url)
const command = `xcrun simctl openurl "${escapeShellArg(device)}" "${escapeShellArg(url)}"`
return shell.exec(command)
},

addphoto: function (device, path) {
const command = util.format('xcrun simctl addphoto "%s" "%s"', device, path)
const command = `xcrun simctl addphoto "${escapeShellArg(device)}" "${escapeShellArg(path)}"`
return shell.exec(command)
},

install: function (device, path) {
const command = util.format('xcrun simctl install "%s" "%s"', device, path)
const command = `xcrun simctl install "${escapeShellArg(device)}" "${escapeShellArg(path)}"`
return shell.exec(command)
},

uninstall: function (device, appIdentifier) {
const command = util.format('xcrun simctl uninstall "%s" "%s"', device, appIdentifier)
const command = `xcrun simctl uninstall "${escapeShellArg(device)}" "${escapeShellArg(appIdentifier)}"`
return shell.exec(command)
},

Expand All @@ -121,8 +124,7 @@ exports = module.exports = {
}).join(' ')
}

const command = util.format('xcrun simctl launch %s "%s" "%s" %s',
waitFlag, device, appIdentifier, argvExpanded)
const command = `xcrun simctl launch ${waitFlag} "${escapeShellArg(device)}" "${escapeShellArg(appIdentifier)}" ${argvExpanded}`;
return shell.exec(command)
},

Expand All @@ -134,7 +136,7 @@ exports = module.exports = {

let archFlag = ''
if (arch) {
archFlag = util.format('--arch="%s"', arch)
archFlag = `--arch="${escapeShellArg(arch)}"', `
}

let argvExpanded = ''
Expand All @@ -144,8 +146,7 @@ exports = module.exports = {
}).join(' ')
}

const command = util.format('xcrun simctl spawn %s %s "%s" "%s" %s',
waitFlag, archFlag, device, pathToExecutable, argvExpanded)
const command = `xcrun simctl spawn ${waitFlag} ${archFlag} "${escapeShellArg(device)}" "${escapeShellArg(pathToExecutable)}" ${argvExpanded}`;
return shell.exec(command)
},

Expand All @@ -163,7 +164,7 @@ exports = module.exports = {
sublist = 'pairs'
}

const command = util.format('xcrun simctl list %s --json', sublist)
const command = `xcrun simctl list ${sublist} --json`
const obj = shell.exec(command, { silent: options.silent })

if (obj.code === 0) {
Expand All @@ -178,17 +179,17 @@ exports = module.exports = {
},

notify_post: function (device, notificationName) {
const command = util.format('xcrun simctl notify_post "%s" "%s"', device, notificationName)
const command = `xcrun simctl notify_post "${escapeShellArg(device)}" "${escapeShellArg(notificationName)}"}`;
return shell.exec(command)
},

icloud_sync: function (device) {
const command = util.format('xcrun simctl icloud_sync "%s"', device)
const command = `xcrun simctl icloud_sync "${escapeShellArg(device)}"`
return shell.exec(command)
},

help: function (subcommand) {
const command = util.format('xcrun simctl help "%s"', subcommand)
const command = `xcrun simctl help "${escapeShellArg(subcommand)}"`
return shell.exec(command)
}
}