@aikidosec/safe-chain 0.0.4-connect-timeout-beta

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.
Files changed (94) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +257 -0
  3. package/bin/aikido-bun.js +14 -0
  4. package/bin/aikido-bunx.js +14 -0
  5. package/bin/aikido-npm.js +14 -0
  6. package/bin/aikido-npx.js +14 -0
  7. package/bin/aikido-pip.js +20 -0
  8. package/bin/aikido-pip3.js +21 -0
  9. package/bin/aikido-pnpm.js +14 -0
  10. package/bin/aikido-pnpx.js +14 -0
  11. package/bin/aikido-python.js +30 -0
  12. package/bin/aikido-python3.js +30 -0
  13. package/bin/aikido-uv.js +16 -0
  14. package/bin/aikido-yarn.js +14 -0
  15. package/bin/safe-chain.js +190 -0
  16. package/docs/banner.svg +151 -0
  17. package/docs/npm-to-binary-migration.md +89 -0
  18. package/docs/safe-package-manager-demo.gif +0 -0
  19. package/docs/safe-package-manager-demo.png +0 -0
  20. package/docs/shell-integration.md +149 -0
  21. package/package.json +68 -0
  22. package/src/api/aikido.js +54 -0
  23. package/src/api/npmApi.js +71 -0
  24. package/src/config/cliArguments.js +138 -0
  25. package/src/config/configFile.js +192 -0
  26. package/src/config/environmentVariables.js +7 -0
  27. package/src/config/settings.js +100 -0
  28. package/src/environment/environment.js +14 -0
  29. package/src/environment/userInteraction.js +122 -0
  30. package/src/main.js +104 -0
  31. package/src/packagemanager/_shared/matchesCommand.js +18 -0
  32. package/src/packagemanager/bun/createBunPackageManager.js +53 -0
  33. package/src/packagemanager/currentPackageManager.js +72 -0
  34. package/src/packagemanager/npm/createPackageManager.js +72 -0
  35. package/src/packagemanager/npm/dependencyScanner/commandArgumentScanner.js +74 -0
  36. package/src/packagemanager/npm/dependencyScanner/nullScanner.js +9 -0
  37. package/src/packagemanager/npm/parsing/parsePackagesFromInstallArgs.js +144 -0
  38. package/src/packagemanager/npm/runNpmCommand.js +25 -0
  39. package/src/packagemanager/npm/utils/abbrevs-generated.js +359 -0
  40. package/src/packagemanager/npm/utils/cmd-list.js +174 -0
  41. package/src/packagemanager/npm/utils/npmCommands.js +34 -0
  42. package/src/packagemanager/npx/createPackageManager.js +15 -0
  43. package/src/packagemanager/npx/dependencyScanner/commandArgumentScanner.js +43 -0
  44. package/src/packagemanager/npx/parsing/parsePackagesFromArguments.js +130 -0
  45. package/src/packagemanager/npx/runNpxCommand.js +25 -0
  46. package/src/packagemanager/pip/createPackageManager.js +21 -0
  47. package/src/packagemanager/pip/pipSettings.js +30 -0
  48. package/src/packagemanager/pip/runPipCommand.js +175 -0
  49. package/src/packagemanager/pnpm/createPackageManager.js +57 -0
  50. package/src/packagemanager/pnpm/dependencyScanner/commandArgumentScanner.js +35 -0
  51. package/src/packagemanager/pnpm/parsing/parsePackagesFromArguments.js +109 -0
  52. package/src/packagemanager/pnpm/runPnpmCommand.js +36 -0
  53. package/src/packagemanager/uv/createUvPackageManager.js +18 -0
  54. package/src/packagemanager/uv/runUvCommand.js +71 -0
  55. package/src/packagemanager/yarn/createPackageManager.js +41 -0
  56. package/src/packagemanager/yarn/dependencyScanner/commandArgumentScanner.js +35 -0
  57. package/src/packagemanager/yarn/parsing/parsePackagesFromArguments.js +128 -0
  58. package/src/packagemanager/yarn/runYarnCommand.js +41 -0
  59. package/src/registryProxy/certBundle.js +95 -0
  60. package/src/registryProxy/certUtils.js +128 -0
  61. package/src/registryProxy/http-utils.js +17 -0
  62. package/src/registryProxy/interceptors/createInterceptorForEcoSystem.js +25 -0
  63. package/src/registryProxy/interceptors/interceptorBuilder.js +140 -0
  64. package/src/registryProxy/interceptors/npm/modifyNpmInfo.js +177 -0
  65. package/src/registryProxy/interceptors/npm/npmInterceptor.js +47 -0
  66. package/src/registryProxy/interceptors/npm/parseNpmPackageUrl.js +43 -0
  67. package/src/registryProxy/interceptors/pipInterceptor.js +115 -0
  68. package/src/registryProxy/mitmRequestHandler.js +231 -0
  69. package/src/registryProxy/plainHttpProxy.js +95 -0
  70. package/src/registryProxy/registryProxy.js +184 -0
  71. package/src/registryProxy/tunnelRequestHandler.js +180 -0
  72. package/src/scanning/audit/index.js +129 -0
  73. package/src/scanning/index.js +82 -0
  74. package/src/scanning/malwareDatabase.js +131 -0
  75. package/src/shell-integration/helpers.js +213 -0
  76. package/src/shell-integration/path-wrappers/templates/unix-wrapper.template.sh +22 -0
  77. package/src/shell-integration/path-wrappers/templates/windows-wrapper.template.cmd +24 -0
  78. package/src/shell-integration/setup-ci.js +170 -0
  79. package/src/shell-integration/setup.js +127 -0
  80. package/src/shell-integration/shellDetection.js +37 -0
  81. package/src/shell-integration/startup-scripts/include-python/init-fish.fish +94 -0
  82. package/src/shell-integration/startup-scripts/include-python/init-posix.sh +81 -0
  83. package/src/shell-integration/startup-scripts/include-python/init-pwsh.ps1 +115 -0
  84. package/src/shell-integration/startup-scripts/init-fish.fish +71 -0
  85. package/src/shell-integration/startup-scripts/init-posix.sh +58 -0
  86. package/src/shell-integration/startup-scripts/init-pwsh.ps1 +92 -0
  87. package/src/shell-integration/supported-shells/bash.js +134 -0
  88. package/src/shell-integration/supported-shells/fish.js +77 -0
  89. package/src/shell-integration/supported-shells/powershell.js +73 -0
  90. package/src/shell-integration/supported-shells/windowsPowershell.js +73 -0
  91. package/src/shell-integration/supported-shells/zsh.js +74 -0
  92. package/src/shell-integration/teardown.js +64 -0
  93. package/src/utils/safeSpawn.js +137 -0
  94. package/tsconfig.json +21 -0
@@ -0,0 +1,137 @@
1
+ import { spawn, execSync } from "child_process";
2
+ import os from "os";
3
+
4
+ /**
5
+ * @param {string} arg
6
+ *
7
+ * @returns {string}
8
+ */
9
+ function sanitizeShellArgument(arg) {
10
+ // If argument contains shell metacharacters, wrap in double quotes
11
+ // and escape characters that are special even inside double quotes
12
+ if (hasShellMetaChars(arg)) {
13
+ // Inside double quotes, we need to escape: " $ ` \
14
+ return '"' + escapeDoubleQuoteContent(arg) + '"';
15
+ }
16
+ return arg;
17
+ }
18
+
19
+ /**
20
+ * @param {string} arg
21
+ *
22
+ * @returns {boolean}
23
+ */
24
+ function hasShellMetaChars(arg) {
25
+ // Shell metacharacters that need escaping
26
+ // These characters have special meaning in shells and need to be quoted
27
+ // Whenever one of these characters is present, we should quote the argument
28
+ // Characters: space, ", &, ', |, ;, <, >, (, ), $, `, \, !, *, ?, [, ], {, }, ~, #
29
+ const shellMetaChars = /[ "&'|;<>()$`\\!*?[\]{}~#]/;
30
+ return shellMetaChars.test(arg);
31
+ }
32
+
33
+ /**
34
+ * @param {string} arg
35
+ *
36
+ * @returns {string}
37
+ */
38
+ function escapeDoubleQuoteContent(arg) {
39
+ // Escape special characters for shell safety
40
+ // This escapes ", $, `, and \ by prefixing them with a backslash
41
+ return arg.replace(/(["`$\\])/g, "\\$1");
42
+ }
43
+
44
+ /**
45
+ * @param {string} command
46
+ * @param {string[]} args
47
+ *
48
+ * @returns {string}
49
+ */
50
+ function buildCommand(command, args) {
51
+ if (args.length === 0) {
52
+ return command;
53
+ }
54
+
55
+ const escapedArgs = args.map(sanitizeShellArgument);
56
+
57
+ return `${command} ${escapedArgs.join(" ")}`;
58
+ }
59
+
60
+ /**
61
+ * @param {string} command
62
+ *
63
+ * @returns {string}
64
+ */
65
+ function resolveCommandPath(command) {
66
+ // command will be "npm", "yarn", etc.
67
+ // Use 'command -v' to find the full path
68
+ const fullPath = execSync(`command -v ${command}`, {
69
+ encoding: "utf8",
70
+ }).trim();
71
+
72
+ if (!fullPath) {
73
+ throw new Error(`Command not found: ${command}`);
74
+ }
75
+
76
+ return fullPath;
77
+ }
78
+
79
+ /**
80
+ * @param {string} command
81
+ * @param {string[]} args
82
+ * @param {import("child_process").SpawnOptions} options
83
+ *
84
+ * @returns {Promise<{status: number, stdout: string, stderr: string}>}
85
+ */
86
+ export async function safeSpawn(command, args, options = {}) {
87
+ // The command is always one of our supported package managers.
88
+ // It should always be alphanumeric or _ or -
89
+ // Reject any command names with suspicious characters
90
+ if (!/^[a-zA-Z0-9_-]+$/.test(command)) {
91
+ throw new Error(`Invalid command name: ${command}`);
92
+ }
93
+
94
+ return new Promise((resolve, reject) => {
95
+ // Windows requires shell: true because .bat and .cmd files are not executable
96
+ // without a terminal. On Unix/macOS, we resolve the full path first, then use
97
+ // array args (safer, no escaping needed).
98
+ // See: https://nodejs.org/api/child_process.html#child_processspawncommand-args-options
99
+ let child;
100
+ if (os.platform() === "win32") {
101
+ const fullCommand = buildCommand(command, args);
102
+ child = spawn(fullCommand, { ...options, shell: true });
103
+ } else {
104
+ const fullPath = resolveCommandPath(command);
105
+ child = spawn(fullPath, args, options);
106
+ }
107
+
108
+ // When stdio is piped, we need to collect the output
109
+ let stdout = "";
110
+ let stderr = "";
111
+
112
+ child.stdout?.on("data", (data) => {
113
+ stdout += data.toString();
114
+ });
115
+
116
+ child.stderr?.on("data", (data) => {
117
+ stderr += data.toString();
118
+ });
119
+
120
+ child.on("close", (code) => {
121
+ // Code is null if it terminated by a signal. This should never
122
+ // happen in our code. If this happens, return 1 error code.
123
+
124
+ code = code ?? 1;
125
+
126
+ resolve({
127
+ status: code,
128
+ stdout: stdout,
129
+ stderr: stderr,
130
+ });
131
+ });
132
+
133
+ child.on("error", (error) => {
134
+ reject(error);
135
+ });
136
+ });
137
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": ["es2023"],
4
+ "module": "node16",
5
+ "strict": true,
6
+ "skipLibCheck": true,
7
+ "moduleResolution": "node16",
8
+ "allowJs": true,
9
+ "checkJs": true,
10
+ "noEmit": true,
11
+ "resolveJsonModule": true
12
+ },
13
+ "include": [
14
+ "src/**/*.js",
15
+ "bin/**/*.js"
16
+ ],
17
+ "exclude": [
18
+ "node_modules",
19
+ "src/**/*.spec.js"
20
+ ]
21
+ }