vibe-guard 1.0.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/LICENSE +21 -0
- package/README.md +200 -0
- package/dist/bin/vibe-guard.d.ts +3 -0
- package/dist/bin/vibe-guard.d.ts.map +1 -0
- package/dist/bin/vibe-guard.js +119 -0
- package/dist/bin/vibe-guard.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +128 -0
- package/dist/index.js.map +1 -0
- package/dist/reporter.d.ts +13 -0
- package/dist/reporter.d.ts.map +1 -0
- package/dist/reporter.js +116 -0
- package/dist/reporter.js.map +1 -0
- package/dist/rules/directory-traversal.d.ts +14 -0
- package/dist/rules/directory-traversal.d.ts.map +1 -0
- package/dist/rules/directory-traversal.js +142 -0
- package/dist/rules/directory-traversal.js.map +1 -0
- package/dist/rules/exposed-secrets.d.ts +13 -0
- package/dist/rules/exposed-secrets.d.ts.map +1 -0
- package/dist/rules/exposed-secrets.js +137 -0
- package/dist/rules/exposed-secrets.js.map +1 -0
- package/dist/rules/hardcoded-sensitive-data.d.ts +13 -0
- package/dist/rules/hardcoded-sensitive-data.d.ts.map +1 -0
- package/dist/rules/hardcoded-sensitive-data.js +104 -0
- package/dist/rules/hardcoded-sensitive-data.js.map +1 -0
- package/dist/rules/index.d.ts +15 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +54 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/insecure-dependencies.d.ts +16 -0
- package/dist/rules/insecure-dependencies.d.ts.map +1 -0
- package/dist/rules/insecure-dependencies.js +152 -0
- package/dist/rules/insecure-dependencies.js.map +1 -0
- package/dist/rules/insecure-http.d.ts +13 -0
- package/dist/rules/insecure-http.d.ts.map +1 -0
- package/dist/rules/insecure-http.js +91 -0
- package/dist/rules/insecure-http.js.map +1 -0
- package/dist/rules/missing-authentication.d.ts +14 -0
- package/dist/rules/missing-authentication.d.ts.map +1 -0
- package/dist/rules/missing-authentication.js +98 -0
- package/dist/rules/missing-authentication.js.map +1 -0
- package/dist/rules/missing-security-headers.d.ts +16 -0
- package/dist/rules/missing-security-headers.d.ts.map +1 -0
- package/dist/rules/missing-security-headers.js +158 -0
- package/dist/rules/missing-security-headers.js.map +1 -0
- package/dist/rules/open-cors.d.ts +11 -0
- package/dist/rules/open-cors.d.ts.map +1 -0
- package/dist/rules/open-cors.js +61 -0
- package/dist/rules/open-cors.js.map +1 -0
- package/dist/rules/sql-injection.d.ts +12 -0
- package/dist/rules/sql-injection.d.ts.map +1 -0
- package/dist/rules/sql-injection.js +95 -0
- package/dist/rules/sql-injection.js.map +1 -0
- package/dist/rules/unvalidated-input.d.ts +13 -0
- package/dist/rules/unvalidated-input.d.ts.map +1 -0
- package/dist/rules/unvalidated-input.js +128 -0
- package/dist/rules/unvalidated-input.js.map +1 -0
- package/dist/scanner.d.ts +15 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +240 -0
- package/dist/scanner.js.map +1 -0
- package/dist/types/index.d.ts +66 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +38 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +72 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Josef
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# Vibe-Guard Security Scanner
|
|
2
|
+
|
|
3
|
+
**Catches the security mistakes we all make when coding fast**
|
|
4
|
+
|
|
5
|
+
Zero dependencies ⢠Instant setup ⢠Works everywhere ⢠10 essential security rules
|
|
6
|
+
|
|
7
|
+
## Quick Start (Choose Your Adventure)
|
|
8
|
+
|
|
9
|
+
### Option 1: One-Line Install (Recommended)
|
|
10
|
+
```bash
|
|
11
|
+
# macOS/Linux - installs to /usr/local/bin
|
|
12
|
+
curl -L https://get-vibe-guard.sh | bash
|
|
13
|
+
|
|
14
|
+
# Then use anywhere:
|
|
15
|
+
vibe-guard scan .
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Option 2: Download Binary Directly
|
|
19
|
+
```bash
|
|
20
|
+
# macOS
|
|
21
|
+
curl -L https://github.com/user/vibe-guard/releases/latest/download/vibe-guard-macos -o vibe-guard
|
|
22
|
+
chmod +x vibe-guard
|
|
23
|
+
./vibe-guard scan .
|
|
24
|
+
|
|
25
|
+
# Linux
|
|
26
|
+
curl -L https://github.com/user/vibe-guard/releases/latest/download/vibe-guard-linux -o vibe-guard
|
|
27
|
+
chmod +x vibe-guard
|
|
28
|
+
./vibe-guard scan .
|
|
29
|
+
|
|
30
|
+
# Windows
|
|
31
|
+
# Download vibe-guard-win.exe from releases page
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Option 3: NPM (for Node.js users)
|
|
35
|
+
```bash
|
|
36
|
+
npx vibe-guard scan .
|
|
37
|
+
# or
|
|
38
|
+
npm install -g vibe-guard
|
|
39
|
+
vibe-guard scan .
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Option 4: Docker (for CI/CD)
|
|
43
|
+
```bash
|
|
44
|
+
# Scan current directory
|
|
45
|
+
docker run --rm -v $(pwd):/code vibe-guard scan /code
|
|
46
|
+
|
|
47
|
+
# Scan specific file
|
|
48
|
+
docker run --rm -v $(pwd):/code vibe-guard scan /code/app.js
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Why You'll Actually Use This
|
|
52
|
+
|
|
53
|
+
- **Zero Setup**: Download and run, no Node.js or dependencies required
|
|
54
|
+
- **Fast Enough to Not Be Annoying**: Scans your entire project in seconds
|
|
55
|
+
- **Won't Spam You**: Smart enough to know test code from real issues
|
|
56
|
+
- **Made by Developers**: We know what actually breaks in production
|
|
57
|
+
- **Works Everywhere**: macOS, Linux, Windows, Docker, CI/CD - you name it
|
|
58
|
+
|
|
59
|
+
## What It Catches (All 10 Rules)
|
|
60
|
+
|
|
61
|
+
### šØ Critical Issues (The Bad)
|
|
62
|
+
- **Exposed API Keys**: AWS, GitHub, Google, Slack, Stripe tokens in your code
|
|
63
|
+
- **Hardcoded Secrets**: Database passwords, JWT secrets, encryption keys
|
|
64
|
+
- **Database URLs**: MongoDB, PostgreSQL connection strings with credentials
|
|
65
|
+
|
|
66
|
+
### ā ļø High-Risk Issues (The Ugly)
|
|
67
|
+
- **Missing Authentication**: Unprotected admin routes and API endpoints
|
|
68
|
+
- **SQL Injection**: String concatenation in database queries
|
|
69
|
+
- **Directory Traversal**: Unsafe file path operations
|
|
70
|
+
- **Open CORS**: Wildcard origins that let anyone access your API
|
|
71
|
+
|
|
72
|
+
### š Medium Issues (The not so Good)
|
|
73
|
+
- **Unvalidated Input**: Direct use of user input without checks
|
|
74
|
+
- **Insecure HTTP**: Using HTTP instead of HTTPS
|
|
75
|
+
- **Vulnerable Dependencies**: Outdated packages with known security issues
|
|
76
|
+
- **Missing Security Headers**: No helmet.js or manual security headers
|
|
77
|
+
|
|
78
|
+
## Usage Examples
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Scan current directory (most common)
|
|
82
|
+
vibe-guard scan .
|
|
83
|
+
|
|
84
|
+
# Scan specific file
|
|
85
|
+
vibe-guard scan app.js
|
|
86
|
+
|
|
87
|
+
# JSON output for CI/CD
|
|
88
|
+
vibe-guard scan . --format json
|
|
89
|
+
|
|
90
|
+
# Quick syntax (same as scan)
|
|
91
|
+
vibe-guard .
|
|
92
|
+
|
|
93
|
+
# Show version
|
|
94
|
+
vibe-guard --version
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## š§ CI/CD Integration
|
|
98
|
+
|
|
99
|
+
### GitHub Actions
|
|
100
|
+
```yaml
|
|
101
|
+
- name: Security Scan
|
|
102
|
+
run: |
|
|
103
|
+
curl -L https://get-vibe-guard.sh | bash
|
|
104
|
+
vibe-guard scan .
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### GitLab CI
|
|
108
|
+
```yaml
|
|
109
|
+
security_scan:
|
|
110
|
+
script:
|
|
111
|
+
- curl -L https://get-vibe-guard.sh | bash
|
|
112
|
+
- vibe-guard scan .
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Docker in CI
|
|
116
|
+
```yaml
|
|
117
|
+
- name: Security Scan
|
|
118
|
+
run: docker run --rm -v $(pwd):/code vibe-guard scan /code
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Who This Is For
|
|
122
|
+
|
|
123
|
+
- **When you're coding with AI** - ChatGPT and Copilot are amazing, but they sometimes miss security basics
|
|
124
|
+
- **Rapid prototyping** - Building something quick? Don't let security be an afterthought
|
|
125
|
+
- **No-code/Low-code folks** - Generated code can have issues, this catches them
|
|
126
|
+
- **Your CI/CD pipeline** - Catch problems before they hit production
|
|
127
|
+
- **Code reviews** - Run this before you submit that PR
|
|
128
|
+
- **Learning security** - Get real-time feedback on what can or is going wrong (and how to fix it)
|
|
129
|
+
|
|
130
|
+
## š Language Support
|
|
131
|
+
|
|
132
|
+
Works with all the languages you actually use:
|
|
133
|
+
- **JavaScript/TypeScript**: .js, .jsx, .ts, .tsx
|
|
134
|
+
- **Python**: .py
|
|
135
|
+
- **PHP**: .php
|
|
136
|
+
- **Ruby**: .rb
|
|
137
|
+
- **Go**: .go
|
|
138
|
+
- **Java**: .java
|
|
139
|
+
- **C#**: .cs
|
|
140
|
+
- **Config files**: .json, .yaml, .yml, .env
|
|
141
|
+
|
|
142
|
+
## šļø Development
|
|
143
|
+
|
|
144
|
+
Want to contribute or build from source?
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Clone and build
|
|
148
|
+
git clone https://github.com/user/vibe-guard.git
|
|
149
|
+
cd vibe-guard
|
|
150
|
+
npm install
|
|
151
|
+
npm run build
|
|
152
|
+
|
|
153
|
+
# Create binaries
|
|
154
|
+
npm run package
|
|
155
|
+
|
|
156
|
+
# Run tests
|
|
157
|
+
npm test
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Project Structure
|
|
161
|
+
```
|
|
162
|
+
src/
|
|
163
|
+
āāā types/ # TypeScript definitions
|
|
164
|
+
āāā rules/ # All 10 security rule implementations
|
|
165
|
+
āāā bin/ # CLI interface
|
|
166
|
+
āāā scanner.ts # File scanning engine
|
|
167
|
+
āāā reporter.ts # Output formatting
|
|
168
|
+
āāā index.ts # Main application
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Comparison
|
|
172
|
+
|
|
173
|
+
| Feature | Vibe-Guard | Other Tools |
|
|
174
|
+
|---------|------------|-------------|
|
|
175
|
+
| Setup Time | 0 seconds | Minutes |
|
|
176
|
+
| Dependencies | Zero | Many |
|
|
177
|
+
| False Positives | Minimal | High |
|
|
178
|
+
| Speed | ā” Fast | š Slow |
|
|
179
|
+
| Languages | All major ones | Limited |
|
|
180
|
+
| CI/CD Ready | ā
Yes | ā ļø Complex |
|
|
181
|
+
| Actually explains fixes | ā
Yes | ā Cryptic |
|
|
182
|
+
|
|
183
|
+
## š¤ Contributing
|
|
184
|
+
|
|
185
|
+
1. **Add Security Rules**: Extend the rule engine with new patterns
|
|
186
|
+
2. **Improve Detection**: Help reduce false positives
|
|
187
|
+
3. **Add Languages**: Support more file types and frameworks
|
|
188
|
+
4. **Better UX**: Improve CLI and output formatting (opportunity for VIM here for enthusiasts)
|
|
189
|
+
|
|
190
|
+
See [SECURITY_RULES.md](SECURITY_RULES.md) for detailed rule documentation.
|
|
191
|
+
|
|
192
|
+
## š License
|
|
193
|
+
|
|
194
|
+
MIT License - Use it anywhere, anytime!
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
**Built with ā¤ļø by developers who got tired of slow, and complex security tools.**
|
|
199
|
+
|
|
200
|
+
*Security shouldn't slow you down, but security holes definitely will.*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vibe-guard.d.ts","sourceRoot":"","sources":["../../src/bin/vibe-guard.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const index_1 = __importDefault(require("../index"));
|
|
10
|
+
const program = new commander_1.Command();
|
|
11
|
+
program
|
|
12
|
+
.name('vibe-guard')
|
|
13
|
+
.description('š”ļø Vibe-Guard Security Scanner - Catch security issues before they catch you!')
|
|
14
|
+
.version('1.0.0');
|
|
15
|
+
// Scan command (main functionality)
|
|
16
|
+
program
|
|
17
|
+
.command('scan')
|
|
18
|
+
.description('Scan files or directories for security issues')
|
|
19
|
+
.argument('<target>', 'File or directory to scan')
|
|
20
|
+
.option('-f, --format <format>', 'Output format (table, json)', 'table')
|
|
21
|
+
.option('-v, --verbose', 'Verbose output', false)
|
|
22
|
+
.option('--exclude <patterns...>', 'Exclude patterns')
|
|
23
|
+
.option('--include <patterns...>', 'Include patterns')
|
|
24
|
+
.action(async (target, options) => {
|
|
25
|
+
try {
|
|
26
|
+
console.log(chalk_1.default.blue.bold('š”ļø Starting Vibe-Guard Security Scan...\n'));
|
|
27
|
+
const scanOptions = {
|
|
28
|
+
target,
|
|
29
|
+
format: options.format,
|
|
30
|
+
verbose: options.verbose,
|
|
31
|
+
exclude: options.exclude,
|
|
32
|
+
include: options.include
|
|
33
|
+
};
|
|
34
|
+
const vibeGuard = new index_1.default();
|
|
35
|
+
const output = await vibeGuard.scanAndFormat(scanOptions);
|
|
36
|
+
console.log(output);
|
|
37
|
+
// Exit with error code if issues found
|
|
38
|
+
const result = await vibeGuard.scan(scanOptions);
|
|
39
|
+
if (result.issuesFound > 0) {
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
console.error(chalk_1.default.red.bold('ā Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
// Default action (scan without explicit 'scan' command for backward compatibility)
|
|
49
|
+
program
|
|
50
|
+
.argument('[target]', 'File or directory to scan')
|
|
51
|
+
.option('-f, --format <format>', 'Output format (table, json)', 'table')
|
|
52
|
+
.option('-v, --verbose', 'Verbose output', false)
|
|
53
|
+
.option('--exclude <patterns...>', 'Exclude patterns')
|
|
54
|
+
.option('--include <patterns...>', 'Include patterns')
|
|
55
|
+
.action(async (target, options) => {
|
|
56
|
+
// Only run if target is provided and no subcommand was used
|
|
57
|
+
if (target && !process.argv.includes('scan') && !process.argv.includes('rules') && !process.argv.includes('version')) {
|
|
58
|
+
try {
|
|
59
|
+
console.log(chalk_1.default.blue.bold('š”ļø Starting Vibe-Guard Security Scan...\n'));
|
|
60
|
+
const scanOptions = {
|
|
61
|
+
target,
|
|
62
|
+
format: options.format,
|
|
63
|
+
verbose: options.verbose,
|
|
64
|
+
exclude: options.exclude,
|
|
65
|
+
include: options.include
|
|
66
|
+
};
|
|
67
|
+
const vibeGuard = new index_1.default();
|
|
68
|
+
const output = await vibeGuard.scanAndFormat(scanOptions);
|
|
69
|
+
console.log(output);
|
|
70
|
+
// Exit with error code if issues found
|
|
71
|
+
const result = await vibeGuard.scan(scanOptions);
|
|
72
|
+
if (result.issuesFound > 0) {
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
console.error(chalk_1.default.red.bold('ā Error:'), error instanceof Error ? error.message : 'Unknown error');
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
program
|
|
83
|
+
.command('rules')
|
|
84
|
+
.description('List all available security rules')
|
|
85
|
+
.action(() => {
|
|
86
|
+
const vibeGuard = new index_1.default();
|
|
87
|
+
const rules = vibeGuard.getRules();
|
|
88
|
+
console.log(chalk_1.default.blue.bold('š”ļø Available Security Rules:\n'));
|
|
89
|
+
rules.forEach(rule => {
|
|
90
|
+
const severityColor = rule.severity === 'critical' ? chalk_1.default.red.bold :
|
|
91
|
+
rule.severity === 'high' ? chalk_1.default.red :
|
|
92
|
+
rule.severity === 'medium' ? chalk_1.default.yellow :
|
|
93
|
+
chalk_1.default.blue;
|
|
94
|
+
console.log(`${chalk_1.default.bold(rule.name)} ${severityColor(`[${rule.severity.toUpperCase()}]`)}`);
|
|
95
|
+
console.log(` ${chalk_1.default.gray(rule.description)}\n`);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
program
|
|
99
|
+
.command('version')
|
|
100
|
+
.description('Show version information')
|
|
101
|
+
.action(() => {
|
|
102
|
+
const vibeGuard = new index_1.default();
|
|
103
|
+
console.log(chalk_1.default.blue.bold('š”ļø Vibe-Guard Security Scanner'));
|
|
104
|
+
console.log(`Version: ${vibeGuard.getVersion()}`);
|
|
105
|
+
console.log('Built for developers who code fast and need security that keeps up! š');
|
|
106
|
+
console.log(chalk_1.default.gray('TypeScript-powered, zero-dependency security scanning'));
|
|
107
|
+
});
|
|
108
|
+
// Handle unhandled promise rejections
|
|
109
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
110
|
+
console.error(chalk_1.default.red.bold('ā Unhandled Rejection at:'), promise, chalk_1.default.red('reason:'), reason);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
});
|
|
113
|
+
// Handle uncaught exceptions
|
|
114
|
+
process.on('uncaughtException', (error) => {
|
|
115
|
+
console.error(chalk_1.default.red.bold('ā Uncaught Exception:'), error);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
});
|
|
118
|
+
program.parse();
|
|
119
|
+
//# sourceMappingURL=vibe-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vibe-guard.js","sourceRoot":"","sources":["../../src/bin/vibe-guard.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ScanOptions, ScanResult, BaseRule } from './types';
|
|
2
|
+
export declare class VibeGuard {
|
|
3
|
+
private scanner;
|
|
4
|
+
private reporter;
|
|
5
|
+
private rules;
|
|
6
|
+
constructor();
|
|
7
|
+
scan(options: ScanOptions): Promise<ScanResult>;
|
|
8
|
+
formatResults(result: ScanResult, format?: 'table' | 'json'): string;
|
|
9
|
+
scanAndFormat(options: ScanOptions): Promise<string>;
|
|
10
|
+
getRules(): BaseRule[];
|
|
11
|
+
getRuleByName(name: string): BaseRule | undefined;
|
|
12
|
+
getVersion(): string;
|
|
13
|
+
}
|
|
14
|
+
export * from './types';
|
|
15
|
+
export * from './rules';
|
|
16
|
+
export { FileScanner } from './scanner';
|
|
17
|
+
export { Reporter } from './reporter';
|
|
18
|
+
export default VibeGuard;
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAY5D,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,KAAK,CAAa;;IAmBpB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAmBrD,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,GAAE,OAAO,GAAG,MAAgB,GAAG,MAAM;IAUvE,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAK1D,QAAQ,IAAI,QAAQ,EAAE;IAItB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAIjD,UAAU,IAAI,MAAM;CASrB;AAGD,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,eAAe,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
36
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.Reporter = exports.FileScanner = exports.VibeGuard = void 0;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const scanner_1 = require("./scanner");
|
|
43
|
+
const reporter_1 = require("./reporter");
|
|
44
|
+
const exposed_secrets_1 = require("./rules/exposed-secrets");
|
|
45
|
+
const missing_authentication_1 = require("./rules/missing-authentication");
|
|
46
|
+
const open_cors_1 = require("./rules/open-cors");
|
|
47
|
+
const hardcoded_sensitive_data_1 = require("./rules/hardcoded-sensitive-data");
|
|
48
|
+
const insecure_http_1 = require("./rules/insecure-http");
|
|
49
|
+
const sql_injection_1 = require("./rules/sql-injection");
|
|
50
|
+
const unvalidated_input_1 = require("./rules/unvalidated-input");
|
|
51
|
+
const directory_traversal_1 = require("./rules/directory-traversal");
|
|
52
|
+
const insecure_dependencies_1 = require("./rules/insecure-dependencies");
|
|
53
|
+
const missing_security_headers_1 = require("./rules/missing-security-headers");
|
|
54
|
+
class VibeGuard {
|
|
55
|
+
constructor() {
|
|
56
|
+
this.rules = [
|
|
57
|
+
new exposed_secrets_1.ExposedSecretsRule(),
|
|
58
|
+
new missing_authentication_1.MissingAuthenticationRule(),
|
|
59
|
+
new open_cors_1.OpenCorsRule(),
|
|
60
|
+
new hardcoded_sensitive_data_1.HardcodedSensitiveDataRule(),
|
|
61
|
+
new insecure_http_1.InsecureHttpRule(),
|
|
62
|
+
new sql_injection_1.SqlInjectionRule(),
|
|
63
|
+
new unvalidated_input_1.UnvalidatedInputRule(),
|
|
64
|
+
new directory_traversal_1.DirectoryTraversalRule(),
|
|
65
|
+
new insecure_dependencies_1.InsecureDependenciesRule(),
|
|
66
|
+
new missing_security_headers_1.MissingSecurityHeadersRule()
|
|
67
|
+
];
|
|
68
|
+
this.scanner = new scanner_1.FileScanner();
|
|
69
|
+
this.reporter = new reporter_1.Reporter();
|
|
70
|
+
}
|
|
71
|
+
async scan(options) {
|
|
72
|
+
const targetPath = path.resolve(options.target);
|
|
73
|
+
// Verify target exists
|
|
74
|
+
if (!fs.existsSync(targetPath)) {
|
|
75
|
+
throw new Error(`Target path does not exist: ${targetPath}`);
|
|
76
|
+
}
|
|
77
|
+
const stats = fs.statSync(targetPath);
|
|
78
|
+
if (stats.isFile()) {
|
|
79
|
+
return await this.scanner.scanFile(targetPath, this.rules);
|
|
80
|
+
}
|
|
81
|
+
else if (stats.isDirectory()) {
|
|
82
|
+
return await this.scanner.scanDirectory(targetPath, this.rules);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
throw new Error(`Target path is neither a file nor a directory: ${targetPath}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
formatResults(result, format = 'table') {
|
|
89
|
+
switch (format) {
|
|
90
|
+
case 'json':
|
|
91
|
+
return this.reporter.formatJson(result);
|
|
92
|
+
case 'table':
|
|
93
|
+
default:
|
|
94
|
+
return this.reporter.formatTable(result);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async scanAndFormat(options) {
|
|
98
|
+
const result = await this.scan(options);
|
|
99
|
+
return this.formatResults(result, options.format);
|
|
100
|
+
}
|
|
101
|
+
getRules() {
|
|
102
|
+
return [...this.rules];
|
|
103
|
+
}
|
|
104
|
+
getRuleByName(name) {
|
|
105
|
+
return this.rules.find(rule => rule.name === name);
|
|
106
|
+
}
|
|
107
|
+
getVersion() {
|
|
108
|
+
try {
|
|
109
|
+
const packagePath = path.join(__dirname, '..', 'package.json');
|
|
110
|
+
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf-8'));
|
|
111
|
+
return packageJson.version || '1.0.0';
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return '1.0.0';
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.VibeGuard = VibeGuard;
|
|
119
|
+
// Export everything for external use
|
|
120
|
+
__exportStar(require("./types"), exports);
|
|
121
|
+
__exportStar(require("./rules"), exports);
|
|
122
|
+
var scanner_2 = require("./scanner");
|
|
123
|
+
Object.defineProperty(exports, "FileScanner", { enumerable: true, get: function () { return scanner_2.FileScanner; } });
|
|
124
|
+
var reporter_2 = require("./reporter");
|
|
125
|
+
Object.defineProperty(exports, "Reporter", { enumerable: true, get: function () { return reporter_2.Reporter; } });
|
|
126
|
+
// Default export
|
|
127
|
+
exports.default = VibeGuard;
|
|
128
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SecurityIssue, ScanResult } from './types';
|
|
2
|
+
export declare class Reporter {
|
|
3
|
+
formatTable(result: ScanResult): string;
|
|
4
|
+
formatJson(result: ScanResult): string;
|
|
5
|
+
private formatSuccess;
|
|
6
|
+
private formatHeader;
|
|
7
|
+
private formatSummary;
|
|
8
|
+
private formatRecommendations;
|
|
9
|
+
private colorSeverity;
|
|
10
|
+
private truncateFilePath;
|
|
11
|
+
formatIssueDetails(issue: SecurityIssue): string;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAiB,MAAM,SAAS,CAAC;AAEnE,qBAAa,QAAQ;IACnB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM;IA8BvC,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM;IAItC,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,aAAa;IAsBrB,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,gBAAgB;IAuBxB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM;CASjD"}
|
package/dist/reporter.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Reporter = void 0;
|
|
7
|
+
const Table = require('cli-table3');
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
class Reporter {
|
|
10
|
+
formatTable(result) {
|
|
11
|
+
if (result.issues.length === 0) {
|
|
12
|
+
return this.formatSuccess(result);
|
|
13
|
+
}
|
|
14
|
+
const table = new Table({
|
|
15
|
+
head: [
|
|
16
|
+
chalk_1.default.bold('Rule'),
|
|
17
|
+
chalk_1.default.bold('Severity'),
|
|
18
|
+
chalk_1.default.bold('File'),
|
|
19
|
+
chalk_1.default.bold('Line'),
|
|
20
|
+
chalk_1.default.bold('Message')
|
|
21
|
+
],
|
|
22
|
+
colWidths: [25, 12, 40, 8, 60],
|
|
23
|
+
wordWrap: true
|
|
24
|
+
});
|
|
25
|
+
result.issues.forEach(issue => {
|
|
26
|
+
table.push([
|
|
27
|
+
issue.rule,
|
|
28
|
+
this.colorSeverity(issue.severity),
|
|
29
|
+
this.truncateFilePath(issue.file),
|
|
30
|
+
issue.line.toString(),
|
|
31
|
+
issue.message
|
|
32
|
+
]);
|
|
33
|
+
});
|
|
34
|
+
return this.formatHeader(result) + '\n\n' + table.toString() + '\n\n' + this.formatSummary(result);
|
|
35
|
+
}
|
|
36
|
+
formatJson(result) {
|
|
37
|
+
return JSON.stringify(result, null, 2);
|
|
38
|
+
}
|
|
39
|
+
formatSuccess(result) {
|
|
40
|
+
const header = chalk_1.default.green.bold('š”ļø Vibe-Guard Security Scan Complete');
|
|
41
|
+
const summary = chalk_1.default.green(`ā
No security issues found in ${result.filesScanned} files`);
|
|
42
|
+
return `${header}\n\n${summary}\n`;
|
|
43
|
+
}
|
|
44
|
+
formatHeader(result) {
|
|
45
|
+
const title = chalk_1.default.red.bold('šØ Vibe-Guard Security Issues Detected');
|
|
46
|
+
const subtitle = chalk_1.default.yellow(`Found ${result.issuesFound} security issues in ${result.filesScanned} files`);
|
|
47
|
+
return `${title}\n${subtitle}`;
|
|
48
|
+
}
|
|
49
|
+
formatSummary(result) {
|
|
50
|
+
const { summary } = result;
|
|
51
|
+
const parts = [];
|
|
52
|
+
if (summary.critical > 0) {
|
|
53
|
+
parts.push(chalk_1.default.red.bold(`${summary.critical} Critical`));
|
|
54
|
+
}
|
|
55
|
+
if (summary.high > 0) {
|
|
56
|
+
parts.push(chalk_1.default.red(`${summary.high} High`));
|
|
57
|
+
}
|
|
58
|
+
if (summary.medium > 0) {
|
|
59
|
+
parts.push(chalk_1.default.yellow(`${summary.medium} Medium`));
|
|
60
|
+
}
|
|
61
|
+
if (summary.low > 0) {
|
|
62
|
+
parts.push(chalk_1.default.blue(`${summary.low} Low`));
|
|
63
|
+
}
|
|
64
|
+
const summaryText = parts.length > 0 ? parts.join(' | ') : 'No issues';
|
|
65
|
+
return chalk_1.default.bold('Summary: ') + summaryText + '\n\n' + this.formatRecommendations();
|
|
66
|
+
}
|
|
67
|
+
formatRecommendations() {
|
|
68
|
+
return chalk_1.default.cyan.bold('š” Recommendations:\n') +
|
|
69
|
+
chalk_1.default.cyan('⢠Review and fix critical and high severity issues immediately\n') +
|
|
70
|
+
chalk_1.default.cyan('⢠Consider implementing security linting in your CI/CD pipeline\n') +
|
|
71
|
+
chalk_1.default.cyan('⢠Run Vibe-Guard regularly during development\n') +
|
|
72
|
+
chalk_1.default.cyan('⢠Check our documentation for detailed fix suggestions');
|
|
73
|
+
}
|
|
74
|
+
colorSeverity(severity) {
|
|
75
|
+
switch (severity) {
|
|
76
|
+
case 'critical':
|
|
77
|
+
return chalk_1.default.red.bold('CRITICAL');
|
|
78
|
+
case 'high':
|
|
79
|
+
return chalk_1.default.red('HIGH');
|
|
80
|
+
case 'medium':
|
|
81
|
+
return chalk_1.default.yellow('MEDIUM');
|
|
82
|
+
case 'low':
|
|
83
|
+
return chalk_1.default.blue('LOW');
|
|
84
|
+
default:
|
|
85
|
+
return String(severity).toUpperCase();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
truncateFilePath(filePath, maxLength = 35) {
|
|
89
|
+
if (filePath.length <= maxLength) {
|
|
90
|
+
return filePath;
|
|
91
|
+
}
|
|
92
|
+
const parts = filePath.split('/');
|
|
93
|
+
if (parts.length <= 2) {
|
|
94
|
+
return filePath;
|
|
95
|
+
}
|
|
96
|
+
// Show first and last parts with ... in between
|
|
97
|
+
const first = parts[0];
|
|
98
|
+
const last = parts[parts.length - 1];
|
|
99
|
+
const truncated = `${first}/.../${last}`;
|
|
100
|
+
if (truncated.length <= maxLength) {
|
|
101
|
+
return truncated;
|
|
102
|
+
}
|
|
103
|
+
// If still too long, just truncate from the beginning
|
|
104
|
+
return '...' + filePath.slice(-(maxLength - 3));
|
|
105
|
+
}
|
|
106
|
+
formatIssueDetails(issue) {
|
|
107
|
+
const header = chalk_1.default.red.bold(`\nšØ ${issue.rule} (${this.colorSeverity(issue.severity)})`);
|
|
108
|
+
const location = chalk_1.default.gray(`š ${issue.file}:${issue.line}:${issue.column}`);
|
|
109
|
+
const message = chalk_1.default.white(`š¬ ${issue.message}`);
|
|
110
|
+
const code = chalk_1.default.gray(`š Code: ${issue.code}`);
|
|
111
|
+
const suggestion = chalk_1.default.green(`š” Suggestion: ${issue.suggestion}`);
|
|
112
|
+
return `${header}\n${location}\n${message}\n${code}\n${suggestion}\n`;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.Reporter = Reporter;
|
|
116
|
+
//# sourceMappingURL=reporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
|