Check powershell execution policy in setup function

This commit is contained in:
Sander Declerck 2026-02-05 09:49:36 +01:00
parent c765438e63
commit e9799e283f
No known key found for this signature in database
5 changed files with 114 additions and 13 deletions

View file

@ -2,6 +2,7 @@ import {
addLineToFile,
doesExecutableExistOnSystem,
removeLinesMatchingPattern,
validatePowerShellExecutionPolicy,
} from "../helpers.js";
import { execSync } from "child_process";
@ -39,6 +40,16 @@ function teardown(tools) {
}
function setup() {
// Check execution policy
const { isValid, policy } = validatePowerShellExecutionPolicy(executableName);
if (!isValid) {
throw new Error(
`PowerShell execution policy is set to '${policy}', which prevents safe-chain from running. ` +
`To fix this, open PowerShell as Administrator and run: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned. ` +
`For more information, see: https://github.com/AikidoSec/safe-chain/blob/main/docs/troubleshooting.md#powershell-execution-policy-blocks-scripts-windows`
);
}
const startupFile = getStartupFile();
addLineToFile(

View file

@ -8,14 +8,20 @@ import { knownAikidoTools } from "../helpers.js";
describe("PowerShell Core shell integration", () => {
let mockStartupFile;
let powershell;
let executionPolicyResult;
beforeEach(async () => {
// Create temporary startup file for testing
mockStartupFile = path.join(
tmpdir(),
`test-powershell-profile-${Date.now()}.ps1`
`test-powershell-profile-${Date.now()}.ps1`,
);
executionPolicyResult = {
isValid: true,
policy: "RemoteSigned",
};
// Mock the helpers module
mock.module("../helpers.js", {
namedExports: {
@ -33,6 +39,7 @@ describe("PowerShell Core shell integration", () => {
const filteredLines = lines.filter((line) => !pattern.test(line));
fs.writeFileSync(filePath, filteredLines.join("\n"), "utf-8");
},
validatePowerShellExecutionPolicy: () => executionPolicyResult,
},
});
@ -76,8 +83,8 @@ describe("PowerShell Core shell integration", () => {
const content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(
content.includes(
'. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1" # Safe-chain PowerShell initialization script'
)
'. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1" # Safe-chain PowerShell initialization script',
),
);
});
});
@ -98,7 +105,7 @@ describe("PowerShell Core shell integration", () => {
const content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(
!content.includes('. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1"')
!content.includes('. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1"'),
);
assert.ok(content.includes("Set-Alias ls "));
assert.ok(content.includes("Set-Alias grep "));
@ -173,14 +180,14 @@ describe("PowerShell Core shell integration", () => {
powershell.setup();
let content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(
content.includes('. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1"')
content.includes('. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1"'),
);
// Teardown
powershell.teardown(knownAikidoTools);
content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(
!content.includes('. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1"')
!content.includes('. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1"'),
);
});
@ -197,4 +204,21 @@ describe("PowerShell Core shell integration", () => {
assert.strictEqual(sourceMatches, 1, "Should not duplicate source lines");
});
});
describe("execution policy", () => {
it(`should throw for restricted policies`, () => {
executionPolicyResult = {
isValid: false,
policy: "Restricted",
};
assert.throws(
() => powershell.setup(),
(err) =>
err.message.startsWith(
"PowerShell execution policy is set to 'Restricted'",
),
);
});
});
});

View file

@ -2,6 +2,7 @@ import {
addLineToFile,
doesExecutableExistOnSystem,
removeLinesMatchingPattern,
validatePowerShellExecutionPolicy,
} from "../helpers.js";
import { execSync } from "child_process";
@ -39,6 +40,16 @@ function teardown(tools) {
}
function setup() {
// Check execution policy
const { isValid, policy } = validatePowerShellExecutionPolicy(executableName);
if (!isValid) {
throw new Error(
`PowerShell execution policy is set to '${policy}', which prevents safe-chain from running. ` +
`To fix this, open PowerShell as Administrator and run: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned. ` +
`For more information, see: https://github.com/AikidoSec/safe-chain/blob/main/docs/troubleshooting.md#powershell-execution-policy-blocks-scripts-windows`
);
}
const startupFile = getStartupFile();
addLineToFile(

View file

@ -8,14 +8,20 @@ import { knownAikidoTools } from "../helpers.js";
describe("Windows PowerShell shell integration", () => {
let mockStartupFile;
let windowsPowershell;
let executionPolicyResult;
beforeEach(async () => {
// Create temporary startup file for testing
mockStartupFile = path.join(
tmpdir(),
`test-windows-powershell-profile-${Date.now()}.ps1`
`test-windows-powershell-profile-${Date.now()}.ps1`,
);
executionPolicyResult = {
isValid: true,
policy: "RemoteSigned",
};
// Mock the helpers module
mock.module("../helpers.js", {
namedExports: {
@ -33,6 +39,7 @@ describe("Windows PowerShell shell integration", () => {
const filteredLines = lines.filter((line) => !pattern.test(line));
fs.writeFileSync(filePath, filteredLines.join("\n"), "utf-8");
},
validatePowerShellExecutionPolicy: () => executionPolicyResult,
},
});
@ -76,8 +83,8 @@ describe("Windows PowerShell shell integration", () => {
const content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(
content.includes(
'. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1" # Safe-chain PowerShell initialization script'
)
'. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1" # Safe-chain PowerShell initialization script',
),
);
});
});
@ -98,7 +105,7 @@ describe("Windows PowerShell shell integration", () => {
const content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(
!content.includes('. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1"')
!content.includes('. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1"'),
);
assert.ok(content.includes("Set-Alias ls "));
assert.ok(content.includes("Set-Alias grep "));
@ -173,14 +180,14 @@ describe("Windows PowerShell shell integration", () => {
windowsPowershell.setup();
let content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(
content.includes('. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1"')
content.includes('. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1"'),
);
// Teardown
windowsPowershell.teardown(knownAikidoTools);
content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(
!content.includes('. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1"')
!content.includes('. "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1"'),
);
});
@ -197,4 +204,21 @@ describe("Windows PowerShell shell integration", () => {
assert.strictEqual(sourceMatches, 1, "Should not duplicate source lines");
});
});
describe("execution policy", () => {
it(`should throw for restricted policies`, () => {
executionPolicyResult = {
isValid: false,
policy: "Restricted",
};
assert.throws(
() => windowsPowershell.setup(),
(err) =>
err.message.startsWith(
"PowerShell execution policy is set to 'Restricted'",
),
);
});
});
});