mirror of
https://github.com/AikidoSec/safe-chain.git
synced 2026-05-26 20:20:49 +00:00
Fix command injection
This commit is contained in:
parent
8ffb0191f5
commit
41bf3252d9
11 changed files with 116 additions and 29 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { execSync, spawnSync } from "child_process";
|
||||
import { spawnSync } from "child_process";
|
||||
import * as os from "os";
|
||||
import fs from "fs";
|
||||
|
||||
|
|
@ -26,14 +26,6 @@ export function doesExecutableExistOnSystem(executableName) {
|
|||
}
|
||||
}
|
||||
|
||||
export function execAndGetOutput(command, shell) {
|
||||
try {
|
||||
return execSync(command, { encoding: "utf8", shell }).trim();
|
||||
} catch (error) {
|
||||
throw new Error(`Command failed: ${command}. Error: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function removeLinesMatchingPattern(filePath, pattern) {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import {
|
||||
addLineToFile,
|
||||
doesExecutableExistOnSystem,
|
||||
execAndGetOutput,
|
||||
removeLinesMatchingPattern,
|
||||
} from "../helpers.js";
|
||||
import { execSync } from "child_process";
|
||||
|
||||
const shellName = "Bash";
|
||||
const executableName = "bash";
|
||||
|
|
@ -14,7 +14,7 @@ function isInstalled() {
|
|||
}
|
||||
|
||||
function teardown() {
|
||||
const startupFile = execAndGetOutput(startupFileCommand, executableName);
|
||||
const startupFile = getStartupFile();
|
||||
|
||||
// Removes all aliases starting with "alias npm=", "alias npx=", or "alias yarn="
|
||||
// This will remove the safe-chain aliases for npm, npx, and yarn commands.
|
||||
|
|
@ -24,7 +24,7 @@ function teardown() {
|
|||
}
|
||||
|
||||
function setup(tools) {
|
||||
const startupFile = execAndGetOutput(startupFileCommand, executableName);
|
||||
const startupFile = getStartupFile();
|
||||
teardown();
|
||||
|
||||
for (const { tool, aikidoCommand } of tools) {
|
||||
|
|
@ -37,6 +37,19 @@ function setup(tools) {
|
|||
return true;
|
||||
}
|
||||
|
||||
function getStartupFile() {
|
||||
try {
|
||||
return execSync(startupFileCommand, {
|
||||
encoding: "utf8",
|
||||
shell: executableName,
|
||||
}).trim();
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Command failed: ${startupFileCommand}. Error: ${error.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: shellName,
|
||||
isInstalled,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ describe("Bash shell integration", () => {
|
|||
// Mock the helpers module
|
||||
mock.module("../helpers.js", {
|
||||
namedExports: {
|
||||
execAndGetOutput: () => mockStartupFile,
|
||||
doesExecutableExistOnSystem: () => true,
|
||||
addLineToFile: (filePath, line) => {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
|
|
@ -33,6 +32,13 @@ describe("Bash shell integration", () => {
|
|||
},
|
||||
});
|
||||
|
||||
// Mock child_process execSync
|
||||
mock.module("child_process", {
|
||||
namedExports: {
|
||||
execSync: () => mockStartupFile,
|
||||
},
|
||||
});
|
||||
|
||||
// Import bash module after mocking
|
||||
bash = (await import("./bash.js")).default;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import {
|
||||
addLineToFile,
|
||||
doesExecutableExistOnSystem,
|
||||
execAndGetOutput,
|
||||
removeLinesMatchingPattern,
|
||||
} from "../helpers.js";
|
||||
import { execSync } from "child_process";
|
||||
|
||||
const shellName = "Fish";
|
||||
const executableName = "fish";
|
||||
|
|
@ -14,7 +14,7 @@ function isInstalled() {
|
|||
}
|
||||
|
||||
function teardown() {
|
||||
const startupFile = execAndGetOutput(startupFileCommand, executableName);
|
||||
const startupFile = getStartupFile();
|
||||
|
||||
// Removes all aliases starting with "alias npm=", "alias npx=", or "alias yarn="
|
||||
// This will remove the safe-chain aliases for npm, npx, and yarn commands.
|
||||
|
|
@ -24,7 +24,7 @@ function teardown() {
|
|||
}
|
||||
|
||||
function setup(tools) {
|
||||
const startupFile = execAndGetOutput(startupFileCommand, executableName);
|
||||
const startupFile = getStartupFile();
|
||||
teardown();
|
||||
|
||||
for (const { tool, aikidoCommand } of tools) {
|
||||
|
|
@ -37,6 +37,19 @@ function setup(tools) {
|
|||
return true;
|
||||
}
|
||||
|
||||
function getStartupFile() {
|
||||
try {
|
||||
return execSync(startupFileCommand, {
|
||||
encoding: "utf8",
|
||||
shell: executableName,
|
||||
}).trim();
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Command failed: ${startupFileCommand}. Error: ${error.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: shellName,
|
||||
isInstalled,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ describe("Fish shell integration", () => {
|
|||
// Mock the helpers module
|
||||
mock.module("../helpers.js", {
|
||||
namedExports: {
|
||||
execAndGetOutput: () => mockStartupFile,
|
||||
doesExecutableExistOnSystem: () => true,
|
||||
addLineToFile: (filePath, line) => {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
|
|
@ -33,6 +32,13 @@ describe("Fish shell integration", () => {
|
|||
}
|
||||
});
|
||||
|
||||
// Mock child_process execSync
|
||||
mock.module("child_process", {
|
||||
namedExports: {
|
||||
execSync: () => mockStartupFile,
|
||||
},
|
||||
});
|
||||
|
||||
// Import fish module after mocking
|
||||
fish = (await import("./fish.js")).default;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import {
|
||||
addLineToFile,
|
||||
doesExecutableExistOnSystem,
|
||||
execAndGetOutput,
|
||||
removeLinesMatchingPattern,
|
||||
} from "../helpers.js";
|
||||
import { execSync } from "child_process";
|
||||
|
||||
const shellName = "PowerShell Core";
|
||||
const executableName = "pwsh";
|
||||
|
|
@ -14,7 +14,7 @@ function isInstalled() {
|
|||
}
|
||||
|
||||
function teardown() {
|
||||
const startupFile = execAndGetOutput(startupFileCommand, executableName);
|
||||
const startupFile = getStartupFile();
|
||||
|
||||
// Removes all aliases starting with "Set-Alias npm=", "Set-Alias npx=", or "Set-Alias yarn="
|
||||
// This will remove the safe-chain aliases for npm, npx, and yarn commands.
|
||||
|
|
@ -24,7 +24,7 @@ function teardown() {
|
|||
}
|
||||
|
||||
function setup(tools) {
|
||||
const startupFile = execAndGetOutput(startupFileCommand, executableName);
|
||||
const startupFile = getStartupFile();
|
||||
teardown();
|
||||
|
||||
for (const { tool, aikidoCommand } of tools) {
|
||||
|
|
@ -37,6 +37,19 @@ function setup(tools) {
|
|||
return true;
|
||||
}
|
||||
|
||||
function getStartupFile() {
|
||||
try {
|
||||
return execSync(startupFileCommand, {
|
||||
encoding: "utf8",
|
||||
shell: executableName,
|
||||
}).trim();
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Command failed: ${startupFileCommand}. Error: ${error.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: shellName,
|
||||
isInstalled,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ describe("PowerShell Core shell integration", () => {
|
|||
// Mock the helpers module
|
||||
mock.module("../helpers.js", {
|
||||
namedExports: {
|
||||
execAndGetOutput: () => mockStartupFile,
|
||||
doesExecutableExistOnSystem: () => true,
|
||||
addLineToFile: (filePath, line) => {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
|
|
@ -33,6 +32,13 @@ describe("PowerShell Core shell integration", () => {
|
|||
}
|
||||
});
|
||||
|
||||
// Mock child_process execSync
|
||||
mock.module("child_process", {
|
||||
namedExports: {
|
||||
execSync: () => mockStartupFile,
|
||||
},
|
||||
});
|
||||
|
||||
// Import powershell module after mocking
|
||||
powershell = (await import("./powershell.js")).default;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import {
|
||||
addLineToFile,
|
||||
doesExecutableExistOnSystem,
|
||||
execAndGetOutput,
|
||||
removeLinesMatchingPattern,
|
||||
} from "../helpers.js";
|
||||
import { execSync } from "child_process";
|
||||
|
||||
const shellName = "Windows PowerShell";
|
||||
const executableName = "powershell";
|
||||
|
|
@ -14,7 +14,7 @@ function isInstalled() {
|
|||
}
|
||||
|
||||
function teardown() {
|
||||
const startupFile = execAndGetOutput(startupFileCommand, executableName);
|
||||
const startupFile = getStartupFile();
|
||||
|
||||
// Removes all aliases starting with "Set-Alias npm=", "Set-Alias npx=", or "Set-Alias yarn="
|
||||
// This will remove the safe-chain aliases for npm, npx, and yarn commands.
|
||||
|
|
@ -24,7 +24,7 @@ function teardown() {
|
|||
}
|
||||
|
||||
function setup(tools) {
|
||||
const startupFile = execAndGetOutput(startupFileCommand, executableName);
|
||||
const startupFile = getStartupFile();
|
||||
teardown();
|
||||
|
||||
for (const { tool, aikidoCommand } of tools) {
|
||||
|
|
@ -37,6 +37,19 @@ function setup(tools) {
|
|||
return true;
|
||||
}
|
||||
|
||||
function getStartupFile() {
|
||||
try {
|
||||
return execSync(startupFileCommand, {
|
||||
encoding: "utf8",
|
||||
shell: executableName,
|
||||
}).trim();
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Command failed: ${startupFileCommand}. Error: ${error.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: shellName,
|
||||
isInstalled,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ describe("Windows PowerShell shell integration", () => {
|
|||
// Mock the helpers module
|
||||
mock.module("../helpers.js", {
|
||||
namedExports: {
|
||||
execAndGetOutput: () => mockStartupFile,
|
||||
doesExecutableExistOnSystem: () => true,
|
||||
addLineToFile: (filePath, line) => {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
|
|
@ -33,6 +32,13 @@ describe("Windows PowerShell shell integration", () => {
|
|||
}
|
||||
});
|
||||
|
||||
// Mock child_process execSync
|
||||
mock.module("child_process", {
|
||||
namedExports: {
|
||||
execSync: () => mockStartupFile,
|
||||
},
|
||||
});
|
||||
|
||||
// Import windowsPowershell module after mocking
|
||||
windowsPowershell = (await import("./windowsPowershell.js")).default;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import {
|
||||
addLineToFile,
|
||||
doesExecutableExistOnSystem,
|
||||
execAndGetOutput,
|
||||
removeLinesMatchingPattern,
|
||||
} from "../helpers.js";
|
||||
import { execSync } from "child_process";
|
||||
|
||||
const shellName = "Zsh";
|
||||
const executableName = "zsh";
|
||||
|
|
@ -14,7 +14,7 @@ function isInstalled() {
|
|||
}
|
||||
|
||||
function teardown() {
|
||||
const startupFile = execAndGetOutput(startupFileCommand, executableName);
|
||||
const startupFile = getStartupFile();
|
||||
|
||||
// Removes all aliases starting with "alias npm=", "alias npx=", or "alias yarn="
|
||||
// This will remove the safe-chain aliases for npm, npx, and yarn commands.
|
||||
|
|
@ -24,7 +24,7 @@ function teardown() {
|
|||
}
|
||||
|
||||
function setup(tools) {
|
||||
const startupFile = execAndGetOutput(startupFileCommand, executableName);
|
||||
const startupFile = getStartupFile();
|
||||
teardown();
|
||||
|
||||
for (const { tool, aikidoCommand } of tools) {
|
||||
|
|
@ -37,6 +37,19 @@ function setup(tools) {
|
|||
return true;
|
||||
}
|
||||
|
||||
function getStartupFile() {
|
||||
try {
|
||||
return execSync(startupFileCommand, {
|
||||
encoding: "utf8",
|
||||
shell: executableName,
|
||||
}).trim();
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Command failed: ${startupFileCommand}. Error: ${error.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: shellName,
|
||||
isInstalled,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ describe("Zsh shell integration", () => {
|
|||
// Mock the helpers module
|
||||
mock.module("../helpers.js", {
|
||||
namedExports: {
|
||||
execAndGetOutput: () => mockStartupFile,
|
||||
doesExecutableExistOnSystem: () => true,
|
||||
addLineToFile: (filePath, line) => {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
|
|
@ -33,6 +32,13 @@ describe("Zsh shell integration", () => {
|
|||
},
|
||||
});
|
||||
|
||||
// Mock child_process execSync
|
||||
mock.module("child_process", {
|
||||
namedExports: {
|
||||
execSync: () => mockStartupFile,
|
||||
},
|
||||
});
|
||||
|
||||
// Import zsh module after mocking
|
||||
zsh = (await import("./zsh.js")).default;
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue