Skip to content

Commit 05e012f

Browse files
committed
add DisableInteractiveMode code integrity setting
1 parent 3da134f commit 05e012f

File tree

3 files changed

+88
-1
lines changed

3 files changed

+88
-1
lines changed

lib/internal/code_integrity.js

+13
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,28 @@
11
'use strict';
22

3+
const { emitWarning } = require('internal/process/warning');
4+
35
let isCodeIntegrityEnforced;
46
let alreadyQueriedSystemCodeEnforcmentMode = false;
57

68
const {
79
isFileTrustedBySystemCodeIntegrityPolicy,
10+
isInteractiveModeDisabled,
811
isSystemEnforcingCodeIntegrity,
912
} = internalBinding('code_integrity');
1013

1114
function isAllowedToExecuteFile(filepath) {
1215
if (!alreadyQueriedSystemCodeEnforcmentMode) {
1316
isCodeIntegrityEnforced = isSystemEnforcingCodeIntegrity();
17+
18+
if (isCodeIntegrityEnforced) {
19+
emitWarning(
20+
'Code integrity is being enforced by system policy.' +
21+
'\nCode integrity is an experimental feature.' +
22+
' See docs for more info.',
23+
'ExperimentalWarning');
24+
}
25+
1426
alreadyQueriedSystemCodeEnforcmentMode = true;
1527
}
1628

@@ -24,5 +36,6 @@ function isAllowedToExecuteFile(filepath) {
2436
module.exports = {
2537
isAllowedToExecuteFile,
2638
isFileTrustedBySystemCodeIntegrityPolicy,
39+
isInteractiveModeDisabled,
2740
isSystemEnforcingCodeIntegrity,
2841
};

lib/internal/main/eval_string.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const {
2525
} = require('internal/errors');
2626

2727
const ci = require('internal/code_integrity');
28-
if (ci.isSystemEnforcingCodeIntegrity()) {
28+
if (ci.isInteractiveModeDisabled()) {
2929
throw new ERR_CODE_INTEGRITY_BLOCKED('"eval"');
3030
}
3131

src/node_code_integrity.cc

+74
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ static pfnWldpGetApplicationSettingBoolean WldpGetApplicationSettingBoolean;
2222
static pfnWldpQuerySecurityPolicy WldpQuerySecurityPolicy;
2323
static PCWSTR NODEJS = L"Node.js";
2424
static PCWSTR ENFORCE_CODE_INTEGRITY_SETTING_NAME = L"EnforceCodeIntegrity";
25+
static PCWSTR DISABLE_INTERPRETIVE_MODE_SETTING_NAME =
26+
L"DisableInteractiveMode";
2527

2628
void InitWldp(Environment* env) {
2729
if (isWldpInitialized) {
@@ -101,6 +103,66 @@ static void IsFileTrustedBySystemCodeIntegrityPolicy(
101103
args.GetReturnValue().Set(isFileTrusted);
102104
}
103105

106+
static void IsInteractiveModeDisabled(
107+
const FunctionCallbackInfo<Value>& args) {
108+
CHECK_EQ(args.Length(), 0);
109+
110+
Environment* env = Environment::GetCurrent(args);
111+
112+
if (!isWldpInitialized) {
113+
InitWldp(env);
114+
}
115+
116+
if (WldpGetApplicationSettingBoolean != nullptr) {
117+
BOOL ret;
118+
HRESULT hr = WldpGetApplicationSettingBoolean(
119+
NODEJS,
120+
DISABLE_INTERPRETIVE_MODE_SETTING_NAME,
121+
&ret);
122+
123+
if (SUCCEEDED(hr)) {
124+
args.GetReturnValue().Set(
125+
Boolean::New(env->isolate(), ret));
126+
return;
127+
} else if (hr != E_NOTFOUND) {
128+
// If the setting is not found, continue through to attempt
129+
// WldpQuerySecurityPolicy, as the setting may be defined
130+
// in the old settings format
131+
args.GetReturnValue().Set(Boolean::New(env->isolate(), false));
132+
return;
133+
}
134+
}
135+
136+
// WldpGetApplicationSettingBoolean is the preferred way for applications to
137+
// query security policy values. However, this method only exists on Windows
138+
// versions going back to circa Win10 2023H2. In order to support systems
139+
// older than that (down to Win10RS2), we can use the deprecated
140+
// WldpQuerySecurityPolicy
141+
if (WldpQuerySecurityPolicy != nullptr) {
142+
DECLARE_CONST_UNICODE_STRING(providerName, L"Node.js");
143+
DECLARE_CONST_UNICODE_STRING(keyName, L"Settings");
144+
DECLARE_CONST_UNICODE_STRING(valueName, L"DisableInteractiveMode");
145+
WLDP_SECURE_SETTING_VALUE_TYPE valueType =
146+
WLDP_SECURE_SETTING_VALUE_TYPE_BOOLEAN;
147+
ULONG valueSize = sizeof(int);
148+
int ret = 0;
149+
HRESULT hr = WldpQuerySecurityPolicy(
150+
&providerName,
151+
&keyName,
152+
&valueName,
153+
&valueType,
154+
&ret,
155+
&valueSize);
156+
if (FAILED(hr)) {
157+
args.GetReturnValue().Set(Boolean::New(env->isolate(), false));
158+
return;
159+
}
160+
161+
args.GetReturnValue().Set(
162+
Boolean::New(env->isolate(), static_cast<bool>(ret)));
163+
}
164+
}
165+
104166
static void IsSystemEnforcingCodeIntegrity(
105167
const FunctionCallbackInfo<Value>& args) {
106168
CHECK_EQ(args.Length(), 0);
@@ -168,6 +230,11 @@ static void IsFileTrustedBySystemCodeIntegrityPolicy(
168230
args.GetReturnValue().Set(true);
169231
}
170232

233+
static void IsInterpretiveModeDisabled(
234+
const FunctionCallbackInfo<Value>& args) {
235+
args.GetReturnValue().Set(false);
236+
}
237+
171238
static void IsSystemEnforcingCodeIntegrity(
172239
const FunctionCallbackInfo<Value>& args) {
173240
args.GetReturnValue().Set(false);
@@ -184,6 +251,12 @@ void Initialize(Local<Object> target,
184251
"isFileTrustedBySystemCodeIntegrityPolicy",
185252
IsFileTrustedBySystemCodeIntegrityPolicy);
186253

254+
SetMethod(
255+
context,
256+
target,
257+
"isInteractiveModeDisabled",
258+
IsInteractiveModeDisabled);
259+
187260
SetMethod(
188261
context,
189262
target,
@@ -193,6 +266,7 @@ void Initialize(Local<Object> target,
193266

194267
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
195268
registry->Register(IsFileTrustedBySystemCodeIntegrityPolicy);
269+
registry->Register(IsInteractiveModeDisabled);
196270
registry->Register(IsSystemEnforcingCodeIntegrity);
197271
}
198272

0 commit comments

Comments
 (0)