powershell-utils 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +16 -2
- package/index.js +12 -9
- package/package.json +1 -1
- package/readme.md +7 -2
package/index.d.ts
CHANGED
|
@@ -1,21 +1,31 @@
|
|
|
1
1
|
import type {ExecFileOptions, ExecFileSyncOptions} from 'node:child_process';
|
|
2
2
|
|
|
3
|
-
export type ExecutePowerShellOptions = ExecFileOptions & {
|
|
3
|
+
export type ExecutePowerShellOptions = Omit<ExecFileOptions, 'shell'> & {
|
|
4
4
|
/**
|
|
5
5
|
Path to PowerShell executable.
|
|
6
6
|
|
|
7
7
|
@default powerShellPath()
|
|
8
8
|
*/
|
|
9
9
|
readonly powerShellPath?: string;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
Not supported. PowerShell is always executed directly to prevent shell injection.
|
|
13
|
+
*/
|
|
14
|
+
readonly shell?: never;
|
|
10
15
|
};
|
|
11
16
|
|
|
12
|
-
export type ExecutePowerShellSyncOptions = ExecFileSyncOptions & {
|
|
17
|
+
export type ExecutePowerShellSyncOptions = Omit<ExecFileSyncOptions, 'shell'> & {
|
|
13
18
|
/**
|
|
14
19
|
Path to PowerShell executable.
|
|
15
20
|
|
|
16
21
|
@default powerShellPath()
|
|
17
22
|
*/
|
|
18
23
|
readonly powerShellPath?: string;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
Not supported. PowerShell is always executed directly to prevent shell injection.
|
|
27
|
+
*/
|
|
28
|
+
readonly shell?: never;
|
|
19
29
|
};
|
|
20
30
|
|
|
21
31
|
export type ExecutePowerShellResult = {
|
|
@@ -105,6 +115,10 @@ export namespace executePowerShell {
|
|
|
105
115
|
/**
|
|
106
116
|
Escape a string argument for use in PowerShell single-quoted strings.
|
|
107
117
|
|
|
118
|
+
This makes a value safe as a PowerShell string literal, not as an argument to a native program. PowerShell removes the outer quotes before passing a value onwards, and the receiving process then re-splits it under its own command-line rules, where spaces and double quotes are delimiters. For example, `Start-Process -ArgumentList` receives `'a b'` as two arguments rather than one.
|
|
119
|
+
|
|
120
|
+
Escaping also does not make an untrusted value safe to use as the program that `Start-Process` runs. Validate such values against an allowlist.
|
|
121
|
+
|
|
108
122
|
@param value - The value to escape.
|
|
109
123
|
@returns Escaped and quoted string ready for PowerShell.
|
|
110
124
|
|
package/index.js
CHANGED
|
@@ -34,10 +34,19 @@ const argumentsPrefix = [
|
|
|
34
34
|
|
|
35
35
|
const encodeCommand = command => Buffer.from(command, 'utf16le').toString('base64');
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
/*
|
|
38
|
+
PowerShell's tokenizer treats the typographic single quotes U+2018, U+2019, U+201A, and U+201B as string delimiters, exactly like the ASCII one, and it does not require the closing quote to match the opening quote. Escaping only the ASCII quote would let any of the others terminate the string and inject a statement. Doubling works for all of them.
|
|
39
|
+
*/
|
|
40
|
+
const escapeArgument = value => `'${String(value).replaceAll(/['‘’‚‛]/g, match => match + match)}'`;
|
|
38
41
|
|
|
39
42
|
const createArguments = command => [...argumentsPrefix, encodeCommand(command)];
|
|
40
43
|
|
|
44
|
+
const createExecFileOptions = options => ({
|
|
45
|
+
encoding: 'utf8',
|
|
46
|
+
...options,
|
|
47
|
+
shell: false,
|
|
48
|
+
});
|
|
49
|
+
|
|
41
50
|
export const executePowerShell = async (command, options = {}) => {
|
|
42
51
|
const {
|
|
43
52
|
powerShellPath: psPath,
|
|
@@ -47,10 +56,7 @@ export const executePowerShell = async (command, options = {}) => {
|
|
|
47
56
|
return execFile(
|
|
48
57
|
psPath ?? powerShellPath(),
|
|
49
58
|
createArguments(command),
|
|
50
|
-
|
|
51
|
-
encoding: 'utf8',
|
|
52
|
-
...execFileOptions,
|
|
53
|
-
},
|
|
59
|
+
createExecFileOptions(execFileOptions),
|
|
54
60
|
);
|
|
55
61
|
};
|
|
56
62
|
|
|
@@ -68,9 +74,6 @@ export const executePowerShellSync = (command, options = {}) => {
|
|
|
68
74
|
return childProcess.execFileSync(
|
|
69
75
|
psPath ?? powerShellPath(),
|
|
70
76
|
createArguments(command),
|
|
71
|
-
|
|
72
|
-
encoding: 'utf8',
|
|
73
|
-
...execFileOptions,
|
|
74
|
-
},
|
|
77
|
+
createExecFileOptions(execFileOptions),
|
|
75
78
|
);
|
|
76
79
|
};
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -76,7 +76,7 @@ The PowerShell command to execute.
|
|
|
76
76
|
|
|
77
77
|
Type: `object`
|
|
78
78
|
|
|
79
|
-
The below option and
|
|
79
|
+
The below option and all options except `shell` in Node.js [`child_process.execFile()`](https://nodejs.org/api/child_process.html#child_processexecfilefile-args-options-callback) are supported. PowerShell is always executed directly to prevent shell injection.
|
|
80
80
|
|
|
81
81
|
##### powerShellPath
|
|
82
82
|
|
|
@@ -126,6 +126,11 @@ Returns: `string`
|
|
|
126
126
|
|
|
127
127
|
Escape a string argument for use in PowerShell single-quoted strings.
|
|
128
128
|
|
|
129
|
+
> [!IMPORTANT]
|
|
130
|
+
> This makes a value safe as a PowerShell string literal, not as an argument to a native program. PowerShell removes the outer quotes before passing a value onwards, and the receiving process then re-splits it under its own command-line rules, where spaces and double quotes are delimiters. For example, `Start-Process -ArgumentList` receives `'a b'` as two arguments rather than one.
|
|
131
|
+
>
|
|
132
|
+
> Escaping also does not make an untrusted value safe to use as the program that `Start-Process` runs. Validate such values against an allowlist.
|
|
133
|
+
|
|
129
134
|
#### value
|
|
130
135
|
|
|
131
136
|
Type: `unknown`
|
|
@@ -187,7 +192,7 @@ The PowerShell command to execute.
|
|
|
187
192
|
|
|
188
193
|
Type: `object`
|
|
189
194
|
|
|
190
|
-
The below option and
|
|
195
|
+
The below option and all options except `shell` in Node.js [`child_process.execFileSync()`](https://nodejs.org/api/child_process.html#child_processexecfilesyncfile-args-options) are supported. PowerShell is always executed directly to prevent shell injection.
|
|
191
196
|
|
|
192
197
|
##### powerShellPath
|
|
193
198
|
|