bun-scan 1.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/LICENSE +22 -0
- package/README.md +338 -0
- package/SECURITY.md +360 -0
- package/package.json +69 -0
- package/src/cli.ts +180 -0
- package/src/client.ts +284 -0
- package/src/config.ts +151 -0
- package/src/constants.ts +121 -0
- package/src/index.ts +58 -0
- package/src/logger.ts +80 -0
- package/src/processor.ts +195 -0
- package/src/retry.ts +86 -0
- package/src/schema.ts +124 -0
- package/src/semver.ts +109 -0
- package/src/severity.ts +103 -0
- package/src/types.ts +28 -0
package/SECURITY.md
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Copyright (c) 2026 rawtoast. All rights reserved.
|
|
3
|
+
Copyright (c) 2025 maloma7. All rights reserved.
|
|
4
|
+
SPDX-License-Identifier: MIT
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
# Security Policy
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
The Bun Scan Scanner is a security-critical component that protects developers from installing vulnerable npm packages. This document outlines our security practices, threat model, and vulnerability reporting procedures.
|
|
12
|
+
|
|
13
|
+
## Supported Versions
|
|
14
|
+
|
|
15
|
+
We provide security updates for the following versions:
|
|
16
|
+
|
|
17
|
+
| Version | Supported |
|
|
18
|
+
| ------- | ------------------ |
|
|
19
|
+
| 1.0.x | :white_check_mark: |
|
|
20
|
+
|
|
21
|
+
## Security Architecture
|
|
22
|
+
|
|
23
|
+
### Threat Model
|
|
24
|
+
|
|
25
|
+
The Bun Scan Scanner operates in a security-sensitive environment and faces several potential threats:
|
|
26
|
+
|
|
27
|
+
#### **1. Supply Chain Attacks**
|
|
28
|
+
|
|
29
|
+
- **Threat**: Malicious actors compromising OSV.dev API responses
|
|
30
|
+
- **Mitigation**:
|
|
31
|
+
- HTTPS-only communication with OSV.dev
|
|
32
|
+
- Response validation using Zod schemas
|
|
33
|
+
- Fail-safe behavior on malformed responses
|
|
34
|
+
|
|
35
|
+
#### **2. API Manipulation Attacks**
|
|
36
|
+
|
|
37
|
+
- **Threat**: Man-in-the-middle attacks on OSV API calls
|
|
38
|
+
- **Mitigation**:
|
|
39
|
+
- Certificate pinning through HTTPS
|
|
40
|
+
- Request/response integrity validation
|
|
41
|
+
- No sensitive data transmitted to external APIs
|
|
42
|
+
|
|
43
|
+
#### **3. Data Injection Attacks**
|
|
44
|
+
|
|
45
|
+
- **Threat**: Malicious package names or versions causing code injection
|
|
46
|
+
- **Mitigation**:
|
|
47
|
+
- All package names/versions are treated as data, never executed
|
|
48
|
+
- TypeScript strict mode prevents type confusion
|
|
49
|
+
- Input sanitization for logging outputs
|
|
50
|
+
|
|
51
|
+
#### **4. Denial of Service (DoS)**
|
|
52
|
+
|
|
53
|
+
- **Threat**: API rate limiting or resource exhaustion
|
|
54
|
+
- **Mitigation**:
|
|
55
|
+
- Configurable request timeouts (30s default)
|
|
56
|
+
- Exponential backoff retry logic
|
|
57
|
+
- Fail-safe behavior (allow installation on scanner errors)
|
|
58
|
+
- Batch query optimization to reduce API calls
|
|
59
|
+
|
|
60
|
+
#### **5. Information Disclosure**
|
|
61
|
+
|
|
62
|
+
- **Threat**: Sensitive data leakage through logs or errors
|
|
63
|
+
- **Mitigation**:
|
|
64
|
+
- Structured logging with configurable levels
|
|
65
|
+
- No credentials or sensitive data in logs
|
|
66
|
+
- Error messages provide minimal information disclosure
|
|
67
|
+
|
|
68
|
+
### Security Design Principles
|
|
69
|
+
|
|
70
|
+
#### **1. Fail-Safe Behavior**
|
|
71
|
+
|
|
72
|
+
The scanner is designed to **never block legitimate installations** due to scanner failures:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
} catch (error) {
|
|
76
|
+
logger.error("OSV scanner encountered an unexpected error", { error: message });
|
|
77
|
+
// Fail-safe: allow installation to proceed on scanner errors
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Rationale**: Developer productivity must not be compromised by scanner infrastructure failures.
|
|
83
|
+
|
|
84
|
+
#### **2. Defense in Depth**
|
|
85
|
+
|
|
86
|
+
Multiple layers of security controls:
|
|
87
|
+
|
|
88
|
+
- **Input Validation**: Zod schema validation for all API responses
|
|
89
|
+
- **Network Security**: HTTPS-only, timeout controls, retry logic
|
|
90
|
+
- **Error Handling**: Graceful degradation with comprehensive error logging
|
|
91
|
+
- **Type Safety**: Full TypeScript coverage with strict compilation
|
|
92
|
+
|
|
93
|
+
#### **3. Principle of Least Privilege**
|
|
94
|
+
|
|
95
|
+
- Scanner operates with minimal permissions
|
|
96
|
+
- No file system write access required
|
|
97
|
+
- Read-only access to package information
|
|
98
|
+
- No external network access beyond OSV.dev API
|
|
99
|
+
|
|
100
|
+
#### **4. Transparency**
|
|
101
|
+
|
|
102
|
+
- All vulnerability data sourced from public OSV.dev database
|
|
103
|
+
- Open source implementation allows security review
|
|
104
|
+
- Comprehensive logging for audit trails
|
|
105
|
+
|
|
106
|
+
## Security Features
|
|
107
|
+
|
|
108
|
+
### **Input Validation**
|
|
109
|
+
|
|
110
|
+
All external data is validated using Zod schemas:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
// OSV API responses validated against strict schemas
|
|
114
|
+
const parsed = OSVBatchResponseSchema.parse(data)
|
|
115
|
+
const vulnerability = OSVVulnerabilitySchema.parse(data)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### **Network Security**
|
|
119
|
+
|
|
120
|
+
- **HTTPS Enforcement**: All OSV.dev API calls use HTTPS
|
|
121
|
+
- **Request Timeouts**: 30-second default timeout prevents hanging
|
|
122
|
+
- **Retry Logic**: Exponential backoff with smart retry conditions
|
|
123
|
+
- **User Agent**: Identifies scanner for OSV.dev monitoring
|
|
124
|
+
|
|
125
|
+
### **Error Handling**
|
|
126
|
+
|
|
127
|
+
- **Fail-Safe**: Scanner errors never block installations
|
|
128
|
+
- **Graceful Degradation**: Partial failures handled appropriately
|
|
129
|
+
- **Comprehensive Logging**: Full error context for debugging
|
|
130
|
+
|
|
131
|
+
### **Data Privacy**
|
|
132
|
+
|
|
133
|
+
- **No Sensitive Data**: Only package names/versions (public data) transmitted
|
|
134
|
+
- **No Local Storage**: No persistent data storage
|
|
135
|
+
- **Minimal Logging**: Only essential information logged
|
|
136
|
+
|
|
137
|
+
## Configuration Security
|
|
138
|
+
|
|
139
|
+
### Environment Variables
|
|
140
|
+
|
|
141
|
+
The scanner supports security-relevant environment variables:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Logging configuration
|
|
145
|
+
OSV_LOG_LEVEL=info # Controls information disclosure in logs
|
|
146
|
+
|
|
147
|
+
# Network security
|
|
148
|
+
OSV_TIMEOUT_MS=30000 # Prevents long-running requests
|
|
149
|
+
OSV_API_BASE_URL=... # Allows custom OSV instances (enterprise)
|
|
150
|
+
OSV_DISABLE_BATCH=false # Performance vs. security tradeoff
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Secure Defaults
|
|
154
|
+
|
|
155
|
+
- Default timeout: 30 seconds (prevents DoS)
|
|
156
|
+
- Default log level: `info` (balances security and debugging)
|
|
157
|
+
- HTTPS enforcement (no HTTP fallback)
|
|
158
|
+
- Batch queries enabled (reduces API surface)
|
|
159
|
+
|
|
160
|
+
## Vulnerability Assessment
|
|
161
|
+
|
|
162
|
+
### Regular Security Practices
|
|
163
|
+
|
|
164
|
+
#### **1. Dependency Management**
|
|
165
|
+
|
|
166
|
+
- Minimal dependency footprint (only Zod for runtime)
|
|
167
|
+
- Regular security audits of dependencies
|
|
168
|
+
- Automated dependency updates through Dependabot
|
|
169
|
+
|
|
170
|
+
#### **2. Code Security**
|
|
171
|
+
|
|
172
|
+
- TypeScript strict mode enabled
|
|
173
|
+
- Comprehensive linting with security rules
|
|
174
|
+
- No `eval()` or dynamic code execution
|
|
175
|
+
- Input sanitization for all external data
|
|
176
|
+
|
|
177
|
+
#### **3. Testing**
|
|
178
|
+
|
|
179
|
+
- Comprehensive test suite including security scenarios
|
|
180
|
+
- Edge case testing for malformed API responses
|
|
181
|
+
- Network failure simulation tests
|
|
182
|
+
|
|
183
|
+
### Known Security Considerations
|
|
184
|
+
|
|
185
|
+
#### **1. OSV.dev API Trust**
|
|
186
|
+
|
|
187
|
+
- **Risk**: Scanner depends on OSV.dev infrastructure integrity
|
|
188
|
+
- **Mitigation**: OSV.dev is Google-operated, industry-standard vulnerability database
|
|
189
|
+
- **Residual Risk**: Acceptable for most use cases
|
|
190
|
+
|
|
191
|
+
#### **2. Network Connectivity**
|
|
192
|
+
|
|
193
|
+
- **Risk**: Scanner requires internet access to function
|
|
194
|
+
- **Mitigation**: Fail-safe behavior allows offline development
|
|
195
|
+
- **Enterprise**: Custom OSV_API_BASE_URL for internal vulnerability databases
|
|
196
|
+
|
|
197
|
+
#### **3. Rate Limiting**
|
|
198
|
+
|
|
199
|
+
- **Risk**: OSV.dev may rate-limit high-volume usage
|
|
200
|
+
- **Mitigation**: Exponential backoff, batch queries, reasonable timeouts
|
|
201
|
+
|
|
202
|
+
## Reporting a Vulnerability
|
|
203
|
+
|
|
204
|
+
### Supported Languages
|
|
205
|
+
|
|
206
|
+
- English
|
|
207
|
+
|
|
208
|
+
### Reporting Process
|
|
209
|
+
|
|
210
|
+
#### **1. Initial Report**
|
|
211
|
+
|
|
212
|
+
Please report security vulnerabilities using **GitHub Security Advisories** at:
|
|
213
|
+
https://github.com/bun-security-scanner/osv/security/advisories/new
|
|
214
|
+
|
|
215
|
+
Include the following information in your report:
|
|
216
|
+
|
|
217
|
+
- **Impact Assessment**: Critical/High/Medium/Low
|
|
218
|
+
- **Vulnerability Type**: Code execution, data disclosure, DoS, etc.
|
|
219
|
+
- **Affected Versions**: Specific versions affected
|
|
220
|
+
- **Proof of Concept**: Steps to reproduce (if applicable)
|
|
221
|
+
- **Suggested Mitigation**: Your recommended fix (optional)
|
|
222
|
+
|
|
223
|
+
#### **2. Response Timeline**
|
|
224
|
+
|
|
225
|
+
- **Initial Response**: Within 3 days
|
|
226
|
+
- **Impact Assessment**: Within 7 days
|
|
227
|
+
- **Security Fix**: Within 14 days for critical, 30 days for others
|
|
228
|
+
- **Public Disclosure**: 90 days after fix release
|
|
229
|
+
|
|
230
|
+
#### **3. Disclosure Policy**
|
|
231
|
+
|
|
232
|
+
We follow **responsible disclosure**:
|
|
233
|
+
|
|
234
|
+
1. **Private Report**: Initial vulnerability report kept confidential
|
|
235
|
+
2. **Coordinated Fix**: We work with reporter to develop fix
|
|
236
|
+
3. **Security Release**: Fixed version released with security advisory
|
|
237
|
+
4. **Public Disclosure**: Full details published after fix deployment
|
|
238
|
+
|
|
239
|
+
### What Qualifies as a Security Vulnerability
|
|
240
|
+
|
|
241
|
+
#### **In Scope**
|
|
242
|
+
|
|
243
|
+
- Code execution vulnerabilities
|
|
244
|
+
- Authentication/authorization bypasses
|
|
245
|
+
- Data disclosure or privacy violations
|
|
246
|
+
- Denial of service attacks
|
|
247
|
+
- Supply chain attack vectors
|
|
248
|
+
- Cryptographic weaknesses
|
|
249
|
+
|
|
250
|
+
#### **Out of Scope**
|
|
251
|
+
|
|
252
|
+
- Issues in dependencies (report to upstream)
|
|
253
|
+
- Social engineering attacks
|
|
254
|
+
- Physical security issues
|
|
255
|
+
- Issues in OSV.dev infrastructure (report to Google)
|
|
256
|
+
- Performance issues without security impact
|
|
257
|
+
|
|
258
|
+
## Security Hardening Guide
|
|
259
|
+
|
|
260
|
+
### For Users
|
|
261
|
+
|
|
262
|
+
#### **1. Environment Security**
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
# Use minimal logging in production
|
|
266
|
+
OSV_LOG_LEVEL=warn
|
|
267
|
+
|
|
268
|
+
# Configure appropriate timeouts for your network
|
|
269
|
+
OSV_TIMEOUT_MS=30000
|
|
270
|
+
|
|
271
|
+
# Use HTTPS-only custom endpoints (enterprise)
|
|
272
|
+
OSV_API_BASE_URL=https://your-internal-osv.company.com/v1
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
#### **2. Network Security**
|
|
276
|
+
|
|
277
|
+
- Ensure HTTPS connectivity to api.osv.dev
|
|
278
|
+
- Configure corporate firewalls to allow OSV.dev access
|
|
279
|
+
- Consider proxy/VPN requirements for enterprise environments
|
|
280
|
+
|
|
281
|
+
#### **3. Monitoring**
|
|
282
|
+
|
|
283
|
+
- Monitor scanner logs for unusual patterns
|
|
284
|
+
- Set up alerts for repeated scanner failures
|
|
285
|
+
- Track vulnerability detection rates
|
|
286
|
+
|
|
287
|
+
### For Developers
|
|
288
|
+
|
|
289
|
+
#### **1. Development Environment**
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
# Enable debug logging for development
|
|
293
|
+
OSV_LOG_LEVEL=debug
|
|
294
|
+
|
|
295
|
+
# Use shorter timeouts for faster feedback
|
|
296
|
+
OSV_TIMEOUT_MS=10000
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
#### **2. Testing**
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
# Test with known vulnerable packages
|
|
303
|
+
bun run src/cli.ts test event-stream@3.3.6
|
|
304
|
+
|
|
305
|
+
# Test network failure handling
|
|
306
|
+
OSV_API_BASE_URL=https://invalid.example.com bun test
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## Incident Response
|
|
310
|
+
|
|
311
|
+
### In Case of Security Incident
|
|
312
|
+
|
|
313
|
+
#### **1. Immediate Actions**
|
|
314
|
+
|
|
315
|
+
- Assess impact and scope
|
|
316
|
+
- Disable scanner if necessary (set empty scanner in bunfig.toml)
|
|
317
|
+
- Notify security team
|
|
318
|
+
- Begin incident documentation
|
|
319
|
+
|
|
320
|
+
#### **2. Investigation**
|
|
321
|
+
|
|
322
|
+
- Collect relevant logs and evidence
|
|
323
|
+
- Determine root cause
|
|
324
|
+
- Assess data exposure risk
|
|
325
|
+
- Document timeline
|
|
326
|
+
|
|
327
|
+
#### **3. Remediation**
|
|
328
|
+
|
|
329
|
+
- Apply security fix
|
|
330
|
+
- Update to latest secure version
|
|
331
|
+
- Review and update security practices
|
|
332
|
+
- Communicate with stakeholders
|
|
333
|
+
|
|
334
|
+
## Compliance and Standards
|
|
335
|
+
|
|
336
|
+
### Security Standards
|
|
337
|
+
|
|
338
|
+
- **OWASP Top 10**: Address common web application security risks
|
|
339
|
+
- **NIST Cybersecurity Framework**: Identify, Protect, Detect, Respond, Recover
|
|
340
|
+
- **Supply Chain Security**: SLSA (Supply chain Levels for Software Artifacts) principles
|
|
341
|
+
|
|
342
|
+
### Audit Trail
|
|
343
|
+
|
|
344
|
+
- All security-relevant events logged with timestamps
|
|
345
|
+
- Vulnerability detection events recorded
|
|
346
|
+
- Configuration changes logged
|
|
347
|
+
- API interactions tracked
|
|
348
|
+
|
|
349
|
+
## Contact Information
|
|
350
|
+
|
|
351
|
+
- **Security Vulnerabilities**: https://github.com/bun-security-scanner/osv/security/advisories/new
|
|
352
|
+
- **General Issues**: https://github.com/bun-security-scanner/osv/issues
|
|
353
|
+
- **Security Advisories**: https://github.com/bun-security-scanner/osv/security
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
**Last Updated**: September 12, 2025
|
|
358
|
+
**Version**: 1.0.0
|
|
359
|
+
|
|
360
|
+
_This security policy is a living document and will be updated as the project evolves and new security considerations emerge._
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bun-scan",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "OSV vulnerability scanner for Bun projects",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"audit",
|
|
7
|
+
"bun",
|
|
8
|
+
"dependencies",
|
|
9
|
+
"osv",
|
|
10
|
+
"scanner",
|
|
11
|
+
"security",
|
|
12
|
+
"security-scanner",
|
|
13
|
+
"vulnerability",
|
|
14
|
+
"vulnerability-scanner"
|
|
15
|
+
],
|
|
16
|
+
"homepage": "https://github.com/RawToast/bun-scan",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/RawToast/bun-scan/issues"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"author": "rawtoast",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/RawToast/bun-scan"
|
|
25
|
+
},
|
|
26
|
+
"funding": {
|
|
27
|
+
"type": "github",
|
|
28
|
+
"url": "https://github.com/sponsors/RawToast"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"CHANGELOG.md",
|
|
32
|
+
"LICENSE",
|
|
33
|
+
"package.json",
|
|
34
|
+
"README.md",
|
|
35
|
+
"SECURITY.md",
|
|
36
|
+
"!src/**/__tests__",
|
|
37
|
+
"src/**/*.ts"
|
|
38
|
+
],
|
|
39
|
+
"type": "module",
|
|
40
|
+
"types": "./src/index.ts",
|
|
41
|
+
"exports": "./src/index.ts",
|
|
42
|
+
"scripts": {
|
|
43
|
+
"dev": "tsgo --watch --noEmit",
|
|
44
|
+
"build": "bun run check",
|
|
45
|
+
"lint": "oxlint",
|
|
46
|
+
"lint:check": "oxlint check",
|
|
47
|
+
"format": "oxfmt",
|
|
48
|
+
"format:check": "oxfmt --check",
|
|
49
|
+
"compile": "tsgo --noEmit",
|
|
50
|
+
"clean": "rm -rf dist build node_modules/.cache",
|
|
51
|
+
"check": "bun format && bun lint:check && bun compile && bun test",
|
|
52
|
+
"prepare": "bunx lefthook install"
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"zod": "4.3.5"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@tsconfig/bun": "1.0.10",
|
|
59
|
+
"@types/bun": "1.3.6",
|
|
60
|
+
"@typescript/native-preview": "7.0.0-dev.20260114.1",
|
|
61
|
+
"lefthook": "2.0.15",
|
|
62
|
+
"oxfmt": "0.24.0",
|
|
63
|
+
"oxlint": "1.39.0"
|
|
64
|
+
},
|
|
65
|
+
"engines": {
|
|
66
|
+
"bun": ">=1.0.0"
|
|
67
|
+
},
|
|
68
|
+
"packageManager": "bun@1.3.0"
|
|
69
|
+
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 maloma7. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { scanner } from "./index.js"
|
|
7
|
+
import { logger } from "./logger.js"
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* CLI interface for testing and debugging the OSV scanner
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
function printUsage() {
|
|
14
|
+
console.log(`
|
|
15
|
+
Bun OSV Scanner CLI
|
|
16
|
+
|
|
17
|
+
Usage:
|
|
18
|
+
bun run src/cli.ts test <package@version> [package@version...]
|
|
19
|
+
bun run src/cli.ts scan <package.json>
|
|
20
|
+
bun run src/cli.ts --help
|
|
21
|
+
|
|
22
|
+
Commands:
|
|
23
|
+
test Test scanning specific packages
|
|
24
|
+
scan Scan packages from a package.json file
|
|
25
|
+
--help Show this help message
|
|
26
|
+
|
|
27
|
+
Examples:
|
|
28
|
+
bun run src/cli.ts test lodash@4.17.20 express@4.18.0
|
|
29
|
+
bun run src/cli.ts test event-stream@3.3.6
|
|
30
|
+
bun run src/cli.ts scan ./package.json
|
|
31
|
+
|
|
32
|
+
Environment Variables:
|
|
33
|
+
OSV_LOG_LEVEL Set logging level (debug, info, warn, error)
|
|
34
|
+
OSV_TIMEOUT_MS Set request timeout in milliseconds
|
|
35
|
+
OSV_DISABLE_BATCH Disable batch queries (true/false)
|
|
36
|
+
`)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function exitWithError(message: string, code: number = 1): never {
|
|
40
|
+
logger.error(message)
|
|
41
|
+
process.exit(code)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function testPackages(packageSpecs: string[]) {
|
|
45
|
+
if (packageSpecs.length === 0) {
|
|
46
|
+
exitWithError("No packages specified for testing")
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const packages: Bun.Security.Package[] = []
|
|
50
|
+
|
|
51
|
+
for (const spec of packageSpecs) {
|
|
52
|
+
const match = spec.match(/^(.+)@(.+)$/)
|
|
53
|
+
if (!match) {
|
|
54
|
+
exitWithError(`Invalid package specification: ${spec}. Use format: package@version`)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const [, name, version] = match
|
|
58
|
+
if (!name || !version) {
|
|
59
|
+
exitWithError(`Invalid package specification: ${spec}`)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
packages.push({
|
|
63
|
+
name,
|
|
64
|
+
version,
|
|
65
|
+
requestedRange: version,
|
|
66
|
+
tarball: `https://registry.npmjs.org/${name}/-/${name}-${version}.tgz`,
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
logger.info(`Testing ${packages.length} packages:`)
|
|
71
|
+
for (const pkg of packages) {
|
|
72
|
+
logger.info(` - ${pkg.name}@${pkg.version}`)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const startTime = Date.now()
|
|
76
|
+
const advisories = await scanner.scan({ packages })
|
|
77
|
+
const duration = Date.now() - startTime
|
|
78
|
+
|
|
79
|
+
console.log(`\\nš Scan Results (completed in ${duration}ms):`)
|
|
80
|
+
console.log(`Packages scanned: ${packages.length}`)
|
|
81
|
+
console.log(`Advisories found: ${advisories.length}\\n`)
|
|
82
|
+
|
|
83
|
+
if (advisories.length === 0) {
|
|
84
|
+
console.log("ā
No security advisories found - all packages appear safe!")
|
|
85
|
+
} else {
|
|
86
|
+
console.log("šØ Security advisories:")
|
|
87
|
+
for (const advisory of advisories) {
|
|
88
|
+
const levelIcon = advisory.level === "fatal" ? "š“" : "ā ļø"
|
|
89
|
+
const levelText = advisory.level.toUpperCase()
|
|
90
|
+
|
|
91
|
+
console.log(`\\n${levelIcon} ${levelText}: ${advisory.package}`)
|
|
92
|
+
if (advisory.description) {
|
|
93
|
+
console.log(` Description: ${advisory.description}`)
|
|
94
|
+
}
|
|
95
|
+
if (advisory.url) {
|
|
96
|
+
console.log(` URL: ${advisory.url}`)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function scanPackageJson(packageJsonPath: string) {
|
|
103
|
+
try {
|
|
104
|
+
const file = Bun.file(packageJsonPath)
|
|
105
|
+
if (!(await file.exists())) {
|
|
106
|
+
exitWithError(`Package.json file not found: ${packageJsonPath}`)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const packageJson = await file.json()
|
|
110
|
+
const dependencies = {
|
|
111
|
+
...packageJson.dependencies,
|
|
112
|
+
...packageJson.devDependencies,
|
|
113
|
+
...packageJson.peerDependencies,
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const packages: Bun.Security.Package[] = []
|
|
117
|
+
for (const [name, versionRange] of Object.entries(dependencies)) {
|
|
118
|
+
// For demo purposes, use the range as the version
|
|
119
|
+
// In reality, you'd need to resolve the actual installed version
|
|
120
|
+
let version = versionRange as string
|
|
121
|
+
|
|
122
|
+
// Clean up common version prefixes
|
|
123
|
+
version = version.replace(/^[~^]/, "")
|
|
124
|
+
|
|
125
|
+
packages.push({
|
|
126
|
+
name,
|
|
127
|
+
version,
|
|
128
|
+
requestedRange: versionRange as string,
|
|
129
|
+
tarball: `https://registry.npmjs.org/${name}/-/${name}-${version}.tgz`,
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
logger.info(`Found ${packages.length} dependencies in ${packageJsonPath}`)
|
|
134
|
+
await testPackages(packages.map((p) => `${p.name}@${p.version}`))
|
|
135
|
+
} catch (error) {
|
|
136
|
+
exitWithError(
|
|
137
|
+
`Failed to read package.json: ${error instanceof Error ? error.message : String(error)}`,
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export async function runCli() {
|
|
143
|
+
const args = process.argv.slice(2)
|
|
144
|
+
|
|
145
|
+
if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
|
|
146
|
+
printUsage()
|
|
147
|
+
return
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const command = args[0]
|
|
151
|
+
const commandArgs = args.slice(1)
|
|
152
|
+
|
|
153
|
+
switch (command) {
|
|
154
|
+
case "test": {
|
|
155
|
+
await testPackages(commandArgs)
|
|
156
|
+
break
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
case "scan": {
|
|
160
|
+
if (commandArgs.length === 0) {
|
|
161
|
+
exitWithError("No package.json file specified")
|
|
162
|
+
}
|
|
163
|
+
const file = commandArgs[0]
|
|
164
|
+
if (!file) {
|
|
165
|
+
exitWithError("Package.json file path required")
|
|
166
|
+
}
|
|
167
|
+
await scanPackageJson(file)
|
|
168
|
+
break
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
default: {
|
|
172
|
+
exitWithError(`Unknown command: ${command}`)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// CLI entry point
|
|
178
|
+
if (import.meta.main) {
|
|
179
|
+
await runCli()
|
|
180
|
+
}
|