vite-plugin-vue-security 1.0.0 → 1.1.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/index.js +166 -179
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -1,179 +1,166 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
// Import the security scanner with
|
|
5
|
-
const { SecurityScanner } = require('vue-security-scanner/src/scanner');
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
message
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
this.
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
console.
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const dir = path.dirname(outputFile);
|
|
168
|
-
if (!fs.existsSync(dir)) {
|
|
169
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
await fs.promises.writeFile(outputFile, JSON.stringify(report, null, 2));
|
|
173
|
-
console.log(`Security report written to ${outputFile}`);
|
|
174
|
-
} catch (error) {
|
|
175
|
-
console.error('Error writing security report:', error.message);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
module.exports = vueSecurityPlugin;
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
// Import the security scanner with rule-based architecture
|
|
5
|
+
const { SecurityScanner } = require('vue-security-scanner/src/scanner');
|
|
6
|
+
const IgnoreManager = require('vue-security-scanner/src/utils/ignore-manager');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Vite Plugin for Vue Security Scanning
|
|
10
|
+
* Performs security scans on Vue.js projects during the build process
|
|
11
|
+
*/
|
|
12
|
+
function vueSecurityPlugin(options = {}) {
|
|
13
|
+
const config = {
|
|
14
|
+
// Default options
|
|
15
|
+
enabled: true,
|
|
16
|
+
failOnError: false, // Whether to fail the build on security issues
|
|
17
|
+
reportLevel: 'warning', // 'error', 'warning', or 'info'
|
|
18
|
+
outputFile: null, // Optional output file for security report
|
|
19
|
+
exclude: [], // Patterns to exclude from scanning
|
|
20
|
+
...options
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
let scanner;
|
|
24
|
+
let ignoreManager;
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
name: 'vue-security',
|
|
28
|
+
enforce: 'pre', // Run before other transforms
|
|
29
|
+
|
|
30
|
+
async buildStart() {
|
|
31
|
+
// Initialize the security scanner with configuration
|
|
32
|
+
const scannerConfig = {
|
|
33
|
+
rules: config.rules || {},
|
|
34
|
+
scan: {
|
|
35
|
+
ignoreDirs: config.ignoreDirs || [],
|
|
36
|
+
ignorePatterns: config.ignorePatterns || [],
|
|
37
|
+
maxSize: config.maxSize || 10,
|
|
38
|
+
maxDepth: config.maxDepth || 10
|
|
39
|
+
},
|
|
40
|
+
output: {
|
|
41
|
+
showProgress: false, // Disable progress in build process
|
|
42
|
+
format: 'json'
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Initialize security scanner
|
|
47
|
+
scanner = new SecurityScanner(scannerConfig);
|
|
48
|
+
|
|
49
|
+
// Initialize ignore manager
|
|
50
|
+
ignoreManager = new IgnoreManager(process.cwd());
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
async transform(code, id) {
|
|
54
|
+
// Skip if disabled
|
|
55
|
+
if (!config.enabled) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Skip excluded files
|
|
60
|
+
if (config.exclude.some(pattern => id.includes(pattern))) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Only scan Vue files and JS/TS files
|
|
65
|
+
if (!id.endsWith('.vue') && !id.endsWith('.js') && !id.endsWith('.ts') && !id.endsWith('.jsx') && !id.endsWith('.tsx')) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Check if file should be ignored
|
|
70
|
+
if (ignoreManager && ignoreManager.shouldIgnoreFile(id)) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
// Perform security scan using new scanner
|
|
76
|
+
const result = await scanner.scanFile(id, code);
|
|
77
|
+
const vulnerabilities = result.vulnerabilities || [];
|
|
78
|
+
|
|
79
|
+
// Report vulnerabilities
|
|
80
|
+
if (vulnerabilities.length > 0) {
|
|
81
|
+
vulnerabilities.forEach(vuln => {
|
|
82
|
+
let message = `[VUE-SECURITY] ${vuln.type} - ${vuln.severity} SEVERITY\n`;
|
|
83
|
+
message += `File: ${vuln.file}\n`;
|
|
84
|
+
if (vuln.line !== 'N/A') {
|
|
85
|
+
message += `Line: ${vuln.line}\n`;
|
|
86
|
+
}
|
|
87
|
+
message += `Description: ${vuln.description}\n`;
|
|
88
|
+
message += `Recommendation: ${vuln.recommendation}\n`;
|
|
89
|
+
if (vuln.ruleId) {
|
|
90
|
+
message += `Rule: ${vuln.ruleId}\n`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Log based on report level
|
|
94
|
+
if (config.reportLevel === 'error' ||
|
|
95
|
+
(config.reportLevel === 'warning' && vuln.severity !== 'Low')) {
|
|
96
|
+
this.error(message);
|
|
97
|
+
} else {
|
|
98
|
+
this.warn(message);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Optionally write to output file
|
|
103
|
+
if (config.outputFile) {
|
|
104
|
+
await writeSecurityReport(config.outputFile, vulnerabilities);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Fail build if configured to do so
|
|
108
|
+
if (config.failOnError) {
|
|
109
|
+
const highSeverityVulns = vulnerabilities.filter(v => v.severity === 'High' || v.severity === 'Critical');
|
|
110
|
+
if (highSeverityVulns.length > 0) {
|
|
111
|
+
this.error(`Build failed due to ${highSeverityVulns.length} high severity security vulnerabilities.`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} catch (error) {
|
|
116
|
+
console.warn(`Security scan error for ${id}:`, error.message);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Return of original code (we're only scanning, not modifying)
|
|
120
|
+
return {
|
|
121
|
+
code,
|
|
122
|
+
map: null // No source map transformation
|
|
123
|
+
};
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
// Hook to generate final report
|
|
127
|
+
async buildEnd(errors) {
|
|
128
|
+
if (errors && errors.length > 0) {
|
|
129
|
+
console.log(`Build completed with ${errors.length} errors.`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Write security report to file
|
|
137
|
+
*/
|
|
138
|
+
async function writeSecurityReport(outputFile, vulnerabilities) {
|
|
139
|
+
try {
|
|
140
|
+
const report = {
|
|
141
|
+
timestamp: new Date().toISOString(),
|
|
142
|
+
totalVulnerabilities: vulnerabilities.length,
|
|
143
|
+
vulnerabilities: vulnerabilities.map(v => ({
|
|
144
|
+
type: v.type,
|
|
145
|
+
severity: v.severity,
|
|
146
|
+
file: v.file,
|
|
147
|
+
line: v.line,
|
|
148
|
+
description: v.description,
|
|
149
|
+
recommendation: v.recommendation,
|
|
150
|
+
ruleId: v.ruleId
|
|
151
|
+
}))
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const dir = path.dirname(outputFile);
|
|
155
|
+
if (!fs.existsSync(dir)) {
|
|
156
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
await fs.promises.writeFile(outputFile, JSON.stringify(report, null, 2));
|
|
160
|
+
console.log(`Security report written to ${outputFile}`);
|
|
161
|
+
} catch (error) {
|
|
162
|
+
console.error('Error writing security report:', error.message);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
module.exports = vueSecurityPlugin;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-vue-security",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "A Vite plugin that performs security scans on Vue.js projects during the build process",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"cheerio": "^1.0.0-rc.12",
|
|
27
|
-
"vue-security-scanner": "^1.1
|
|
27
|
+
"vue-security-scanner": "^1.2.1"
|
|
28
28
|
},
|
|
29
29
|
"repository": {
|
|
30
30
|
"type": "git",
|