snyk 1.1114.0 → 1.1115.0

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.
package/.snyk ADDED
@@ -0,0 +1,20 @@
1
+ # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
2
+ version: v1.25.0
3
+ # ignores vulnerabilities until expiry date; change duration by modifying expiry date
4
+ ignore:
5
+ SNYK-JS-SNYK-3037342:
6
+ - '*':
7
+ reason: Based on default version number
8
+ expires: 2030-01-10T00:00:00.000Z
9
+ created: 2023-03-03T14:26:54.682Z
10
+ SNYK-JS-SNYK-3038622:
11
+ - '*':
12
+ reason: Based on default version number
13
+ expires: 2030-01-10T00:00:00.000Z
14
+ created: 2023-03-03T14:32:41.690Z
15
+ SNYK-JS-SNYK-3111871:
16
+ - '*':
17
+ reason: Based on default version number
18
+ expires: 2030-01-10T00:00:00.000Z
19
+ created: 2023-03-03T14:33:35.717Z
20
+ patch: {}
package/bin/snyk CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- require('../dist/cli/index.js');
2
+ require('../wrapper_dist/index.js');
package/jest.config.js ADDED
@@ -0,0 +1,3 @@
1
+ const { createJestConfig } = require('../test/createJestConfig');
2
+
3
+ module.exports = createJestConfig({ displayName: 'ts-binary-wrapper' });
package/package.json CHANGED
@@ -1,21 +1,13 @@
1
1
  {
2
2
  "name": "snyk",
3
- "version": "1.1114.0",
3
+ "version": "1.1115.0",
4
4
  "description": "snyk library and cli utility",
5
5
  "files": [
6
- "help/cli-commands",
7
- "dist",
8
- "bin",
9
- "pysrc",
10
- "config.default.json",
11
- "SECURITY.md",
12
- "LICENSE",
13
- "README.md"
6
+ "*"
14
7
  ],
15
8
  "directories": {
16
9
  "lib": "src",
17
- "test": "test",
18
- "doc": "help/cli-commands"
10
+ "test": "test"
19
11
  },
20
12
  "bin": {
21
13
  "snyk": "bin/snyk"
@@ -23,27 +15,11 @@
23
15
  "engines": {
24
16
  "node": ">=12"
25
17
  },
26
- "workspaces": [
27
- "packages/*"
28
- ],
29
18
  "scripts": {
30
- "clean": "npx rimraf node_modules dist binary-releases test-results *.tgz tsconfig.tsbuildinfo .eslintcache pysrc packages/*/node_modules packages/*/dist packages/*/tsconfig.tsbuildinfo packages/*/*.tgz",
31
- "format": "prettier --write '**/*.{js,ts,json,yaml,yml,md}' && npm run lint:js -- --fix",
32
- "format:changes": "./scripts/format/prettier-changes.sh",
33
- "lint": "npm-run-all --serial --continue-on-error lint:*",
34
- "lint:js": "eslint --quiet --color --cache '**/*.{js,ts}'",
35
- "lint:formatting": "prettier --check '**/*.{js,ts,json,yaml,yml,md}'",
36
- "build": "patch-package && npm run build:dev",
37
- "build:dev": "patch-package && npm run build --workspaces && npm run build-cli:dev",
38
- "build:prod": "patch-package && npm run build --workspaces && npm run build-cli:prod",
39
- "build-cli:dev": "node --max-old-space-size=8192 node_modules/webpack/bin/webpack.js --config webpack.dev.ts",
40
- "build-cli:prod": "node --max-old-space-size=8192 node_modules/webpack/bin/webpack.js --config webpack.prod.ts",
41
- "watch": "npm run build-cli:dev -- --watch",
42
- "test": "npm run test:unit && npm run test:acceptance && npm run test:tap",
43
- "test:unit": "jest --runInBand --testPathPattern '/test(/jest)?/unit/'",
44
- "test:acceptance": "jest --runInBand --testPathPattern '/test(/jest)?/acceptance/'",
45
- "test:tap": "tap -Rspec --timeout=300 --node-arg=-r --node-arg=ts-node/register test/tap/*.test.* ",
46
- "test:smoke": "./scripts/run-smoke-tests-locally.sh"
19
+ "clean": "npx rimraf wrapper_dist tsconfig.tsbuildinfo",
20
+ "build": "tsc && cp -R src/generated wrapper_dist/",
21
+ "test": "npx jest test/*",
22
+ "postinstall": "node wrapper_dist/bootstrap.js exec"
47
23
  },
48
24
  "keywords": [
49
25
  "security",
@@ -58,25 +34,22 @@
58
34
  ],
59
35
  "author": "snyk.io",
60
36
  "license": "Apache-2.0",
61
- "dependencies": {},
62
- "devDependencies": {},
63
37
  "repository": {
64
38
  "type": "git",
65
39
  "url": "https://github.com/snyk/snyk.git"
66
40
  },
67
- "pkg": {
68
- "scripts": [
69
- "dist/**/*.js",
70
- "bin/snyk"
71
- ],
72
- "assets": [
73
- "config.default.json",
74
- "dist",
75
- "help"
76
- ]
77
- },
78
41
  "publishConfig": {
79
42
  "registry": "https://registry.npmjs.org/",
80
43
  "access": "public"
44
+ },
45
+ "devDependencies": {
46
+ "jest": "^29.4.1",
47
+ "rimraf": "^4.1.2",
48
+ "ts-jest": "^29.0.5",
49
+ "typescript": "^4.9.5"
50
+ },
51
+ "dependencies": {
52
+ "@sentry/node": "^7.36.0",
53
+ "global-agent": "^3.0.0"
81
54
  }
82
55
  }
@@ -0,0 +1,27 @@
1
+ import * as common from './common';
2
+ import * as process from 'process';
3
+
4
+ const errorContextMessage = 'Download Error';
5
+
6
+ (async () => {
7
+ try {
8
+ const config = common.getCurrentConfiguration();
9
+ const executable = config.getLocalLocation();
10
+
11
+ if (process.argv.includes('exec')) {
12
+ const filenameShasum = config.getShasumFile();
13
+ const downloadUrl = config.getDownloadLocation();
14
+
15
+ const downloadError = await common.downloadExecutable(
16
+ downloadUrl,
17
+ executable,
18
+ filenameShasum,
19
+ );
20
+ if (downloadError !== undefined) {
21
+ throw downloadError;
22
+ }
23
+ }
24
+ } catch (err) {
25
+ await common.logError(errorContextMessage, err);
26
+ }
27
+ })();
package/src/common.ts ADDED
@@ -0,0 +1,375 @@
1
+ // must be set before we import 'global-agent/bootstrap'
2
+ process.env.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE = '';
3
+ process.env.HTTPS_PROXY =
4
+ process.env.HTTPS_PROXY ?? process.env.https_proxy ?? '';
5
+ process.env.HTTP_PROXY = process.env.HTTP_PROXY ?? process.env.http_proxy ?? '';
6
+ process.env.NO_PROXY = process.env.NO_PROXY ?? process.env.no_proxy ?? '';
7
+
8
+ import 'global-agent/bootstrap';
9
+ import * as path from 'path';
10
+ import * as os from 'os';
11
+ import * as fs from 'fs';
12
+ import { spawnSync } from 'child_process';
13
+ import * as https from 'https';
14
+ import { createHash } from 'crypto';
15
+ import * as Sentry from '@sentry/node';
16
+
17
+ export const versionFile = path.join(__dirname, 'generated', 'version');
18
+ export const shasumFile = path.join(__dirname, 'generated', 'sha256sums.txt');
19
+ const binaryDeploymentsFilePath = path.join(
20
+ __dirname,
21
+ 'generated',
22
+ 'binary-deployments.json',
23
+ );
24
+
25
+ export class WrapperConfiguration {
26
+ private version: string;
27
+ private binaryName: string;
28
+ private expectedSha256sum: string;
29
+
30
+ public constructor(
31
+ version: string,
32
+ binaryName: string,
33
+ expectedSha256sum: string,
34
+ ) {
35
+ this.version = version;
36
+ this.binaryName = binaryName;
37
+ this.expectedSha256sum = expectedSha256sum;
38
+ }
39
+
40
+ public getVersion(): string {
41
+ return this.version;
42
+ }
43
+
44
+ public getBinaryName(): string {
45
+ return this.binaryName;
46
+ }
47
+
48
+ public getDownloadLocation(): string {
49
+ const baseUrl = 'https://static.snyk.io/cli/v';
50
+ return baseUrl + this.version + '/' + this.binaryName;
51
+ }
52
+
53
+ public getLocalLocation(): string {
54
+ const currentFolder = __dirname;
55
+ return path.join(currentFolder, this.binaryName);
56
+ }
57
+
58
+ public getShasumFile(): string {
59
+ return this.expectedSha256sum;
60
+ }
61
+ }
62
+
63
+ export function determineBinaryName(platform: string, arch: string): string {
64
+ let osname = platform;
65
+ let archname = arch;
66
+
67
+ switch (osname) {
68
+ case 'win32':
69
+ osname = 'windows';
70
+ break;
71
+ case 'linux': {
72
+ let isAlpine = false;
73
+ try {
74
+ const result = spawnSync('cat /etc/os-release', { shell: true });
75
+ isAlpine = result.stdout
76
+ .toString()
77
+ .toLowerCase()
78
+ .includes('id=alpine');
79
+ } catch {
80
+ isAlpine = false;
81
+ }
82
+
83
+ if (isAlpine) {
84
+ osname = 'alpine';
85
+ }
86
+
87
+ break;
88
+ }
89
+ }
90
+
91
+ switch (arch) {
92
+ case 'x64':
93
+ case 'amd64':
94
+ archname = 'amd64';
95
+ break;
96
+ }
97
+
98
+ const supportedPlatforms = require(binaryDeploymentsFilePath);
99
+ const binaryName = supportedPlatforms[osname][archname];
100
+
101
+ if (binaryName === undefined) {
102
+ const defaultErrorMsg =
103
+ ' The current platform (' +
104
+ osname +
105
+ ' ' +
106
+ archname +
107
+ ') is not supported by Snyk.\n' +
108
+ ' You may want to consider using Docker to run Snyk, for details see: https://docs.snyk.io/snyk-cli/install-the-snyk-cli#snyk-cli-in-a-docker-image\n' +
109
+ ' If you experience errors please check http://support.snyk.io/.';
110
+ throw Error(getWarningMessage(defaultErrorMsg));
111
+ }
112
+
113
+ return binaryName;
114
+ }
115
+
116
+ export function getCurrentVersion(filename: string): string {
117
+ try {
118
+ const version = fs.readFileSync(filename);
119
+ return version.toString().trim();
120
+ } catch {
121
+ return '';
122
+ }
123
+ }
124
+
125
+ export function getCurrentSha256sum(
126
+ binaryName: string,
127
+ filename: string,
128
+ ): string {
129
+ try {
130
+ const allsums = fs.readFileSync(filename).toString();
131
+ const re = new RegExp('^([a-zA-Z0-9]+)[\\s\\*]+' + binaryName + '$', 'mig');
132
+ const result = re.exec(allsums);
133
+ if (result) {
134
+ return result[1];
135
+ }
136
+ } catch {
137
+ //
138
+ }
139
+
140
+ return 'unknown-shasum-' + binaryName;
141
+ }
142
+
143
+ export function getCurrentConfiguration(): WrapperConfiguration {
144
+ const binaryName = determineBinaryName(os.platform(), os.arch());
145
+ const version = getCurrentVersion(versionFile);
146
+ const expectedSha256sum = getCurrentSha256sum(binaryName, shasumFile);
147
+ return new WrapperConfiguration(version, binaryName, expectedSha256sum);
148
+ }
149
+
150
+ export function getCliArguments(inputArgv: string[]): string[] {
151
+ const cliArguments = inputArgv.slice(2);
152
+ return cliArguments;
153
+ }
154
+
155
+ export function debugEnabled(cliArguments: string[]): boolean {
156
+ let debugIndex = cliArguments.indexOf('--debug');
157
+
158
+ if (debugIndex < 0) {
159
+ debugIndex = cliArguments.indexOf('-d');
160
+ }
161
+
162
+ return debugIndex >= 0;
163
+ }
164
+
165
+ export function runWrapper(executable: string, cliArguments: string[]): number {
166
+ interface SpawnError extends Error {
167
+ errno: number;
168
+ code: string;
169
+ syscall: string;
170
+ path: string;
171
+ spawnargs: string[];
172
+ }
173
+
174
+ const debug = debugEnabled(cliArguments);
175
+
176
+ if (debug) {
177
+ console.error('Executing: ' + executable + ' ' + cliArguments.join(' '));
178
+ }
179
+
180
+ const res = spawnSync(executable, cliArguments, {
181
+ shell: false,
182
+ stdio: 'inherit',
183
+ });
184
+
185
+ if (res.status !== null) {
186
+ if (debug) {
187
+ console.error(res);
188
+ }
189
+
190
+ return res.status;
191
+ } else {
192
+ console.error(res);
193
+ if (!formatErrorMessage((res.error as SpawnError).code)) {
194
+ console.error('Failed to spawn child process. (' + executable + ')');
195
+ }
196
+
197
+ return 2;
198
+ }
199
+ }
200
+
201
+ export function getWarningMessage(message: string): string {
202
+ return `\n------------------------------- Warning -------------------------------\n${message}\n------------------------------- Warning -------------------------------\n`;
203
+ }
204
+
205
+ export function formatErrorMessage(message: string): boolean {
206
+ const eaccesWarning =
207
+ "You don't have the permissions to install Snyk. Please try the following options:\n" +
208
+ '* If you are installing with increased privileges (for example sudo), try adding --unsafe-perm as a parameter to npm install\n' +
209
+ '* If you run NPM <= 6, please upgrade to a later version.\n' +
210
+ 'If the problems persist please check http://support.snyk.io/.';
211
+
212
+ const certificateError =
213
+ 'If you are running Snyk in an environment that intercepts SSL traffic, please specify\n' +
214
+ 'your custom CA certificates via the NODE_EXTRA_CA_CERTS environment variable.\n' +
215
+ 'See https://nodejs.org/api/cli.html#node_extra_ca_certsfile for additional information.';
216
+
217
+ const degradedCLIWarning =
218
+ 'You are currently running a degraded version of the Snyk CLI.\n' +
219
+ 'As a result, some features of the CLI will be unavailable.\n' +
220
+ 'For information on how to resolve this, please see this article: https://docs.snyk.io/snyk-cli/installing-snyk-cli-as-a-binary-via-npm\n' +
221
+ 'For any assistance, please check http://support.snyk.io/.';
222
+
223
+ let warning = '';
224
+
225
+ if (message.includes('EACCES')) {
226
+ warning = eaccesWarning;
227
+ } else if (message.includes('certificate')) {
228
+ warning = certificateError;
229
+ } else if (message.includes('legacy-cli')) {
230
+ warning = degradedCLIWarning;
231
+ } else {
232
+ return false;
233
+ }
234
+
235
+ console.error(getWarningMessage(warning));
236
+ return true;
237
+ }
238
+
239
+ export function downloadExecutable(
240
+ downloadUrl: string,
241
+ filename: string,
242
+ filenameShasum: string,
243
+ ): Promise<Error | undefined> {
244
+ return new Promise<Error | undefined>(function(resolve) {
245
+ const options = new URL(downloadUrl);
246
+ const temp = path.join(__dirname, Date.now().toString());
247
+ const fileStream = fs.createWriteStream(temp);
248
+ const shasum = createHash('sha256');
249
+
250
+ const cleanupAfterError = (error: Error) => {
251
+ try {
252
+ fs.unlinkSync(temp);
253
+ } catch (e) {
254
+ // ignoring any error during cleaning up after an error
255
+ }
256
+
257
+ resolve(error);
258
+ };
259
+
260
+ // shasum events
261
+ shasum.on('error', cleanupAfterError);
262
+
263
+ // filestream events
264
+ fileStream.on('error', (e) => {
265
+ cleanupAfterError(e);
266
+ });
267
+
268
+ fileStream.on('finish', () => {
269
+ // compare shasums
270
+ const actualShasum = shasum.digest('hex');
271
+
272
+ const debugMessage =
273
+ 'Shasums:\n- actual: ' +
274
+ actualShasum +
275
+ '\n- expected: ' +
276
+ filenameShasum;
277
+
278
+ if (filenameShasum && actualShasum != filenameShasum) {
279
+ cleanupAfterError(Error('Shasum comparison failed!\n' + debugMessage));
280
+ } else {
281
+ console.error(debugMessage);
282
+
283
+ // finally rename the file and change permissions
284
+ fs.renameSync(temp, filename);
285
+ fs.chmodSync(filename, 0o755);
286
+ console.error('Downloaded successfull! ');
287
+ }
288
+
289
+ resolve(undefined);
290
+ });
291
+
292
+ console.error(
293
+ "Downloading from '" + downloadUrl + "' to '" + filename + "'",
294
+ );
295
+
296
+ const req = https.request(options, (res) => {
297
+ // response events
298
+ res.on('error', cleanupAfterError);
299
+ res.on('end', () => {
300
+ shasum.end();
301
+ fileStream.end();
302
+ });
303
+
304
+ // pipe data
305
+ res.pipe(fileStream);
306
+ res.pipe(shasum);
307
+ });
308
+
309
+ req.on('error', (e) => {
310
+ cleanupAfterError(e);
311
+ });
312
+
313
+ req.on('response', (incoming) => {
314
+ if (
315
+ incoming.statusCode &&
316
+ !(200 <= incoming.statusCode && incoming.statusCode < 300)
317
+ ) {
318
+ req.destroy();
319
+ cleanupAfterError(
320
+ Error(
321
+ 'Download failed! Server Response: ' +
322
+ incoming.statusCode +
323
+ ' ' +
324
+ incoming.statusMessage +
325
+ ' (' +
326
+ downloadUrl +
327
+ ')',
328
+ ),
329
+ );
330
+ }
331
+ });
332
+
333
+ req.end();
334
+ });
335
+ }
336
+
337
+ export async function logError(
338
+ context: string,
339
+ err,
340
+ printToConsole = true,
341
+ ): Promise<void> {
342
+ if (isAnalyticsEnabled()) {
343
+ // init error reporting
344
+ const version = getCurrentVersion(versionFile);
345
+ Sentry.init({
346
+ dsn:
347
+ 'https://3e845233db8c4f43b4c4b9245f1d7bd6@o30291.ingest.sentry.io/4504599528079360',
348
+ release: version,
349
+ });
350
+
351
+ // report error
352
+ const sentryError = new Error('[' + context + '] ' + err.message);
353
+ sentryError.stack = err.stack;
354
+ Sentry.captureException(sentryError);
355
+ await Sentry.close();
356
+ }
357
+
358
+ // finally log the error to the console as well
359
+ if (printToConsole) {
360
+ console.error('\n');
361
+ console.error(err);
362
+ formatErrorMessage(err.message);
363
+ }
364
+ }
365
+
366
+ export function isAnalyticsEnabled(): boolean {
367
+ if (
368
+ process.env.snyk_disable_analytics == '1' ||
369
+ process.env.SNYK_DISABLE_ANALYTICS == '1'
370
+ ) {
371
+ return false;
372
+ }
373
+
374
+ return true;
375
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "darwin": {
3
+ "amd64": "snyk-macos",
4
+ "arm64": "snyk-macos"
5
+ },
6
+ "windows": {
7
+ "amd64": "snyk-win.exe"
8
+ },
9
+ "alpine": {
10
+ "amd64": "snyk-alpine"
11
+ },
12
+ "linux": {
13
+ "amd64": "snyk-linux",
14
+ "arm64": "snyk-linux-arm64"
15
+ }
16
+ }
@@ -0,0 +1,10 @@
1
+ 6505c380a999d92fb32058c8ad3b00d0f3d38f24b7931c509d5d038f08283e4b docker-mac-signed-bundle.tar.gz
2
+ e5d33e097cecae5a06cf8823f96d87d1cb19e5ac3f9e7533121dc195df71915f snyk-alpine
3
+ 79f87f12fc866d6ef6221e65449ebc5e5acd02c172908149c4fe52fb1d695399 snyk-fix.tgz
4
+ cd6b42c1576213deb43381fbca47121c1b797342c8f36101ec41d1cc427aae04 snyk-for-docker-desktop-darwin-arm64.tar.gz
5
+ 0c9e8cf7e99b2767510edd008cc4a9f3147e207d5e310ffd8317e3e54cf97a64 snyk-for-docker-desktop-darwin-x64.tar.gz
6
+ 8ff5c2555fde80b227a3ee53aecf378ef780e2adc20aaa80b14d11ac981b2b28 snyk-linux-arm64
7
+ 9f13c7f7ff53984c9556185fb8945c5517b73934ca76538575e1ec998c086911 snyk-linux
8
+ 0aad5b3b4f11679cb37ad7f95726ea01cf4cd7ada3bd8a70fca3bc843791f260 snyk-macos
9
+ f36e5c2138452e16c2c242748ec6ec0299144adc05a84a47e2844892181e9c6b snyk-protect.tgz
10
+ 0397c9e6f91e1542faa2b9594dfa4cfda478becbedf501874fa4c19175c1d9b5 snyk-win.exe
@@ -0,0 +1 @@
1
+ 1.1115.0
package/src/index.ts ADDED
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { argv } from 'process';
4
+ import * as common from './common';
5
+ import * as fs from 'fs';
6
+ import * as path from 'path';
7
+
8
+ const errorContextMessage = 'Runtime';
9
+ const fallbackScript = path.join(__dirname, '..', 'dist', 'cli', 'index.js');
10
+ const legacyCLIflag = '--legacy-cli';
11
+
12
+ function run(executable: string): number {
13
+ let cliArguments = common.getCliArguments(argv);
14
+
15
+ if (executable.endsWith('.js')) {
16
+ cliArguments = [executable].concat(cliArguments);
17
+ executable = argv[0]; // node runtime
18
+ }
19
+
20
+ const exitCode = common.runWrapper(executable, cliArguments);
21
+ return exitCode;
22
+ }
23
+
24
+ (async () => {
25
+ let fallbackToLegacyCLI = argv.includes(legacyCLIflag);
26
+
27
+ if (fallbackToLegacyCLI === false) {
28
+ try {
29
+ const config = common.getCurrentConfiguration();
30
+ const executable = config.getLocalLocation();
31
+
32
+ if (!fs.existsSync(executable)) {
33
+ console.error("Executable doesn't exist, trying to download.");
34
+
35
+ const downloadError = await common.downloadExecutable(
36
+ config.getDownloadLocation(),
37
+ executable,
38
+ config.getShasumFile(),
39
+ );
40
+ if (downloadError !== undefined) {
41
+ throw downloadError;
42
+ }
43
+ }
44
+
45
+ // run the executable
46
+ process.exit(run(executable));
47
+ } catch (error) {
48
+ fallbackToLegacyCLI = true;
49
+ await common.logError(errorContextMessage, error);
50
+ }
51
+ } else {
52
+ // if --legacy-clli is enabled create a log messaeg
53
+ await common.logError(
54
+ errorContextMessage,
55
+ Error(legacyCLIflag + ' is set'),
56
+ false,
57
+ );
58
+ }
59
+
60
+ if (fallbackToLegacyCLI) {
61
+ common.formatErrorMessage('legacy-cli');
62
+ const exitCode = run(fallbackScript);
63
+ common.formatErrorMessage('legacy-cli');
64
+
65
+ process.exit(exitCode);
66
+ }
67
+ })();