@involvex/bun-scanner 1.0.0 → 2.0.1

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@involvex/bun-scanner",
3
- "description": "Bun security scanner ",
4
- "version": "1.0.0",
3
+ "description": "Enhanced Bun security scanner with real-time vulnerability detection, automated dependency auditing, and AI-driven anomaly detection",
4
+ "version": "2.0.1",
5
5
  "author": "involvex",
6
6
  "license": "MIT",
7
7
  "exports": {
@@ -15,11 +15,27 @@
15
15
  "keywords": [
16
16
  "bun",
17
17
  "security",
18
- "provider"
18
+ "scanner",
19
+ "vulnerability",
20
+ "dependency",
21
+ "audit",
22
+ "threat",
23
+ "detection"
19
24
  ],
25
+ "scripts": {
26
+ "test": "bun test",
27
+ "prebuild": "bunx prettier . --write && tsc --noEmit",
28
+ "build": "bun build src/index.ts --outdir dist"
29
+ },
20
30
  "devDependencies": {
21
31
  "@types/bun": "^1.3.5",
22
32
  "prettier": "^3.7.4",
23
33
  "typescript": "^5.9.3"
34
+ },
35
+ "dependencies": {
36
+ "zod": "^3.22.4",
37
+ "axios": "^1.6.2",
38
+ "lodash": "^4.17.21",
39
+ "semver": "^7.5.4"
24
40
  }
25
41
  }
package/scanner.test.ts CHANGED
@@ -1,34 +1,24 @@
1
1
  import {expect, test} from 'bun:test';
2
2
  import {scanner} from './src/index.ts';
3
3
 
4
- /////////////////////////////////////////////////////////////////////////////////////
5
- // This test file is mostly just here to get you up and running quickly. It's
6
- // likely you'd want to improve or remove this, and add more coverage for your
7
- // own code.
8
- /////////////////////////////////////////////////////////////////////////////////////
9
-
10
4
  test('Scanner should warn about known malicious packages', async () => {
11
5
  const advisories = await scanner.scan({
12
6
  packages: [
13
7
  {
14
8
  name: 'event-stream',
15
- version: '3.3.6', // This was a known incident in 2018 - https://blog.npmjs.org/post/180565383195/details-about-the-event-stream-incident
9
+ version: '3.3.6',
16
10
  requestedRange: '^3.3.0',
17
11
  tarball: 'https://registry.npmjs.org/event-stream/-/event-stream-3.3.6.tgz',
12
+ license: 'MIT',
18
13
  },
19
14
  ],
20
15
  });
21
16
 
22
17
  expect(advisories.length).toBeGreaterThan(0);
23
- const advisory = advisories[0]!;
24
- expect(advisory).toBeDefined();
25
18
 
26
- expect(advisory).toMatchObject({
27
- level: 'fatal',
28
- package: 'event-stream',
29
- url: expect.any(String),
30
- description: expect.any(String),
31
- });
19
+ const eventStreamAdvisory = advisories.find(a => a.package === 'event-stream');
20
+ expect(eventStreamAdvisory).toBeDefined();
21
+ expect(eventStreamAdvisory?.level).toBe('fatal');
32
22
  });
33
23
 
34
24
  test('There should be no advisories if no packages are being installed', async () => {
@@ -36,80 +26,153 @@ test('There should be no advisories if no packages are being installed', async (
36
26
  expect(advisories.length).toBe(0);
37
27
  });
38
28
 
39
- test('Safe packages should return no advisories', async () => {
29
+ test('Should handle packages without specified licenses', async () => {
40
30
  const advisories = await scanner.scan({
41
31
  packages: [
42
32
  {
43
- name: 'lodash',
44
- version: '4.17.21',
45
- requestedRange: '^4.17.0',
46
- tarball: 'https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz',
33
+ name: 'unlicensed-package',
34
+ version: '1.0.0',
35
+ requestedRange: '^1.0.0',
36
+ tarball: 'https://registry.npmjs.org/unlicensed-package/-/unlicensed-package-1.0.0.tgz',
47
37
  },
48
38
  ],
49
39
  });
50
- expect(advisories.length).toBe(0);
40
+
41
+ const licenseAdvisory = advisories.find(a =>
42
+ a.description?.includes('Package has no specified license'),
43
+ );
44
+
45
+ expect(licenseAdvisory).toBeDefined();
46
+ expect(licenseAdvisory?.level).toBe('warn');
51
47
  });
52
48
 
53
- test('Should handle multiple packages with mixed security status', async () => {
49
+ test('Should handle scoped packages correctly', async () => {
54
50
  const advisories = await scanner.scan({
55
51
  packages: [
56
52
  {
57
- name: 'event-stream',
58
- version: '3.3.6', // malicious
59
- requestedRange: '^3.3.0',
60
- tarball: 'https://registry.npmjs.org/event-stream/-/event-stream-3.3.6.tgz',
53
+ name: '@types/node',
54
+ version: '20.0.0',
55
+ requestedRange: '^20.0.0',
56
+ tarball: 'https://registry.npmjs.org/@types/node/-/node-20.0.0.tgz',
57
+ license: 'MIT',
58
+ },
59
+ ],
60
+ });
61
+
62
+ const licenseAdvisories = advisories.filter(a =>
63
+ a.description?.includes('Package has no specified license'),
64
+ );
65
+
66
+ expect(licenseAdvisories.length).toBe(0);
67
+ });
68
+
69
+ test('Should detect vulnerabilities in lodash versions before 4.17.21', async () => {
70
+ const advisories = await scanner.scan({
71
+ packages: [
72
+ {
73
+ name: 'lodash',
74
+ version: '4.17.20',
75
+ requestedRange: '^4.17.0',
76
+ tarball: 'https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz',
77
+ license: 'MIT',
61
78
  },
79
+ ],
80
+ });
81
+
82
+ const lodashAdvisory = advisories.find(a => a.package === 'lodash');
83
+ expect(lodashAdvisory).toBeDefined();
84
+ expect(lodashAdvisory?.level).toBe('warn');
85
+ });
86
+
87
+ test('Should not detect vulnerabilities in lodash 4.17.21 or later', async () => {
88
+ const advisories = await scanner.scan({
89
+ packages: [
62
90
  {
63
91
  name: 'lodash',
64
- version: '4.17.21', // safe
92
+ version: '4.17.21',
65
93
  requestedRange: '^4.17.0',
66
94
  tarball: 'https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz',
95
+ license: 'MIT',
67
96
  },
68
97
  ],
69
98
  });
70
99
 
71
- expect(advisories.length).toBe(1);
72
- expect(advisories[0]?.package).toBe('event-stream');
100
+ const lodashAdvisory = advisories.find(a => a.package === 'lodash');
101
+ expect(lodashAdvisory).toBeUndefined();
73
102
  });
74
103
 
75
- test('Should differentiate between versions of the same package', async () => {
76
- const maliciousVersion = await scanner.scan({
104
+ test('Should prioritize critical vulnerabilities first', async () => {
105
+ const advisories = await scanner.scan({
77
106
  packages: [
78
107
  {
79
108
  name: 'event-stream',
80
- version: '3.3.6', // malicious version
81
- requestedRange: '3.3.6',
109
+ version: '3.3.6',
110
+ requestedRange: '^3.3.0',
82
111
  tarball: 'https://registry.npmjs.org/event-stream/-/event-stream-3.3.6.tgz',
112
+ license: 'MIT',
113
+ },
114
+ {
115
+ name: 'lodash',
116
+ version: '4.17.20',
117
+ requestedRange: '^4.17.0',
118
+ tarball: 'https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz',
119
+ license: 'MIT',
83
120
  },
84
121
  ],
85
122
  });
86
123
 
87
- const safeVersion = await scanner.scan({
124
+ expect(advisories.length).toBeGreaterThan(1);
125
+ expect(advisories[0]?.level).toBe('fatal');
126
+ expect(advisories[0]?.package).toBe('event-stream');
127
+ expect(advisories[1]?.level).toBe('warn');
128
+ expect(advisories[1]?.package).toBe('lodash');
129
+ });
130
+
131
+ test('Should return advisories with detailed information', async () => {
132
+ const advisories = await scanner.scan({
88
133
  packages: [
89
134
  {
90
135
  name: 'event-stream',
91
- version: '4.0.0', // safe version
92
- requestedRange: '4.0.0',
93
- tarball: 'https://registry.npmjs.org/event-stream/-/event-stream-4.0.0.tgz',
136
+ version: '3.3.6',
137
+ requestedRange: '^3.3.0',
138
+ tarball: 'https://registry.npmjs.org/event-stream/-/event-stream-3.3.6.tgz',
139
+ license: 'MIT',
94
140
  },
95
141
  ],
96
142
  });
97
143
 
98
- expect(maliciousVersion.length).toBeGreaterThan(0);
99
- expect(safeVersion.length).toBe(0);
144
+ const advisory = advisories[0];
145
+ expect(advisory).toBeDefined();
146
+ expect(advisory?.package).toBe('event-stream');
147
+ expect(advisory?.description).toBeDefined();
148
+ expect(advisory?.url).toBeDefined();
100
149
  });
101
150
 
102
- test('Should handle scoped packages correctly', async () => {
151
+ test('Should handle multiple packages with mixed security status', async () => {
103
152
  const advisories = await scanner.scan({
104
153
  packages: [
105
154
  {
106
- name: '@types/node',
107
- version: '20.0.0',
108
- requestedRange: '^20.0.0',
109
- tarball: 'https://registry.npmjs.org/@types/node/-/node-20.0.0.tgz',
155
+ name: 'event-stream',
156
+ version: '3.3.6',
157
+ requestedRange: '^3.3.0',
158
+ tarball: 'https://registry.npmjs.org/event-stream/-/event-stream-3.3.6.tgz',
159
+ license: 'MIT',
160
+ },
161
+ {
162
+ name: 'lodash',
163
+ version: '4.17.21',
164
+ requestedRange: '^4.17.0',
165
+ tarball: 'https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz',
166
+ license: 'MIT',
110
167
  },
111
168
  ],
112
169
  });
113
170
 
114
- expect(advisories.length).toBe(0);
171
+ expect(advisories.length).toBeGreaterThan(0);
172
+
173
+ const eventStreamAdvisory = advisories.find(a => a.package === 'event-stream');
174
+ expect(eventStreamAdvisory).toBeDefined();
175
+
176
+ const lodashAdvisory = advisories.find(a => a.package === 'lodash');
177
+ expect(lodashAdvisory).toBeUndefined();
115
178
  });