Skip to content

Commit debf2da

Browse files
RafaelGSSaduh95
authored andcommitted
permission: prefer --permission over audit mode
When both --permission and --permission-audit are set, run in enforce mode as documented, instead of only reporting denials and keeping the environment variables. Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com> PR-URL: #67036 Reviewed-By: Ulises Gascón <ulisesgascongonzalez@gmail.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
1 parent dfb6dba commit debf2da

5 files changed

Lines changed: 50 additions & 4 deletions

File tree

‎lib/internal/process/permission.js‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ module.exports = ObjectFreeze({
5353
isAuditMode() {
5454
if (_audit === undefined) {
5555
const { getOptionValue } = require('internal/options');
56-
_audit = getOptionValue('--permission-audit');
56+
// --permission takes precedence over --permission-audit.
57+
_audit = getOptionValue('--permission-audit') &&
58+
!getOptionValue('--permission');
5759
}
5860
return _audit;
5961
},

‎src/env.cc‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,7 +1111,9 @@ Environment::Environment(IsolateData* isolate_data,
11111111
if (options_->permission || options_->permission_audit) {
11121112
permission()->EnablePermissions();
11131113
static const std::array args = {std::string("*")};
1114-
if (options_->permission_audit) {
1114+
// --permission takes precedence over --permission-audit.
1115+
const bool audit_only = options_->permission_audit && !options_->permission;
1116+
if (audit_only) {
11151117
permission()->EnableWarningOnly();
11161118
}
11171119
// The process shouldn't be able to neither
@@ -1121,7 +1123,7 @@ Environment::Environment(IsolateData* isolate_data,
11211123
// In audit mode addon loading must stay enabled: the denial is
11221124
// published through the diagnostics channel by the permission
11231125
// check in DLOpen() instead of being rejected upfront.
1124-
if (!options_->permission_audit) {
1126+
if (!audit_only) {
11251127
options_->allow_native_addons = false;
11261128
}
11271129
permission()->Apply(this, args, permission::PermissionScope::kAddon);

‎src/node.cc‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1412,7 +1412,8 @@ InitializeOncePerProcessInternal(
14121412
permission::ParseEnvAllowList(env_options->allow_env);
14131413
const bool allow_all =
14141414
std::find(allow.begin(), allow.end(), "*") != allow.end();
1415-
if (env_options->permission_audit && !allow_all) {
1415+
if (env_options->permission_audit && !env_options->permission &&
1416+
!allow_all) {
14161417
// In audit mode nothing is removed, but accesses to the variables that
14171418
// enforcing the permission model would remove are published.
14181419
permission::RecordAuditedEnvironmentVariables(allow);

‎test/parallel/test-permission-audit-fs-does-not-deny.js‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,34 @@ test('permission-audit logs fs denial without throwing', () => {
5757
test('permission-audit logs fs denial without throwing (eval)', () => {
5858
runAudit('eval');
5959
});
60+
61+
// --permission takes precedence over --permission-audit, so the read is denied.
62+
function runEnforced(args, extraEnv) {
63+
const { status, stdout, stderr } = spawnSync(
64+
process.execPath,
65+
[...args, '-e', `
66+
try {
67+
require('node:fs').readFileSync(${JSON.stringify(blockedFile)});
68+
console.log('RESULT NO_THROW');
69+
} catch (e) {
70+
console.log('RESULT THREW ' + e.code);
71+
}
72+
`],
73+
{ encoding: 'utf8', env: { ...process.env, ...extraEnv } },
74+
);
75+
assert.strictEqual(status, 0, stderr);
76+
assert.ok(stdout.split('\n').includes('RESULT THREW ERR_ACCESS_DENIED'),
77+
stdout);
78+
}
79+
80+
test('--permission takes precedence over --permission-audit', () => {
81+
runEnforced(['--permission', '--permission-audit']);
82+
});
83+
84+
test('--permission takes precedence over --permission-audit in NODE_OPTIONS', {
85+
skip: process.config.variables.node_without_node_options &&
86+
'missing NODE_OPTIONS support',
87+
}, () => {
88+
runEnforced(['--permission'], { NODE_OPTIONS: '--permission-audit' });
89+
runEnforced(['--permission-audit'], { NODE_OPTIONS: '--permission' });
90+
});

‎test/parallel/test-permission-env-scrub.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,16 @@ function run(...flags) {
125125
assert.strictEqual(result.hasAll, false);
126126
}
127127

128+
// --permission takes precedence over --permission-audit.
129+
{
130+
const result = run(
131+
'--permission', '--permission-audit', '--allow-env=PERMISSION_ENV_ALLOWED');
132+
assert.deepStrictEqual(result.keys, ['PERMISSION_ENV_ALLOWED', 'TZ']);
133+
assert.strictEqual(result.has.PERMISSION_ENV_SECRET, false);
134+
assert.strictEqual(result.has.PERMISSION_ENV_ALLOWED, true);
135+
assert.strictEqual(result.hasAll, false);
136+
}
137+
128138
// --allow-env requires the permission model.
129139
spawnSyncAndExit(
130140
process.execPath,

0 commit comments

Comments
 (0)