sec-gate 0.1.0 → 0.1.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 +11 -2
- package/scripts/postinstall.js +64 -30
package/package.json
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sec-gate",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Pre-commit security gate for OWASP Top 10 2021 — SAST, SCA and misconfig checks for Node/Express, Go and React codebases",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Sundram Bhardwaj",
|
|
7
|
+
"email": "bhardwajsundram0@gmail.com",
|
|
8
|
+
"url": "https://github.com/SUNDRAMBHARDWAJ"
|
|
9
|
+
},
|
|
5
10
|
"bin": {
|
|
6
11
|
"sec-gate": "bin/sec-gate.js"
|
|
7
12
|
},
|
|
@@ -19,13 +24,17 @@
|
|
|
19
24
|
"keywords": [
|
|
20
25
|
"security",
|
|
21
26
|
"owasp",
|
|
27
|
+
"owasp-top-10",
|
|
22
28
|
"sast",
|
|
23
29
|
"sca",
|
|
24
30
|
"pre-commit",
|
|
31
|
+
"git-hook",
|
|
25
32
|
"semgrep",
|
|
26
33
|
"osv-scanner",
|
|
27
34
|
"govulncheck",
|
|
28
|
-
"cli"
|
|
35
|
+
"cli",
|
|
36
|
+
"devsecops",
|
|
37
|
+
"supply-chain"
|
|
29
38
|
],
|
|
30
39
|
"repository": {
|
|
31
40
|
"type": "git",
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,17 +1,41 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* sec-gate postinstall script
|
|
5
|
+
*
|
|
6
|
+
* PURPOSE: This script runs after `npm install -g sec-gate` to set up bundled
|
|
7
|
+
* scanning tools so developers need only one install command.
|
|
8
|
+
*
|
|
9
|
+
* WHAT IT DOES (transparently):
|
|
10
|
+
* [1/3] Downloads the osv-scanner binary from Google's official GitHub release
|
|
11
|
+
* URL: https://github.com/google/osv-scanner/releases/
|
|
12
|
+
* Only downloads if not already present. No data is sent anywhere.
|
|
13
|
+
*
|
|
14
|
+
* [2/3] Installs govulncheck using `go install` from golang.org/x/vuln
|
|
15
|
+
* Only runs if Go is installed AND SEC_GATE_GO_INSTALL=1 is set,
|
|
16
|
+
* OR if Go is installed and this is the first time running.
|
|
17
|
+
* Skipped silently if Go is not found.
|
|
18
|
+
*
|
|
19
|
+
* [3/3] Installs a git pre-commit hook in the current directory
|
|
20
|
+
* if it is a git repo. Backs up any existing hook first.
|
|
21
|
+
* Skipped silently if not inside a git repo.
|
|
22
|
+
*
|
|
23
|
+
* OPT-OUT: Set SEC_GATE_SKIP_POSTINSTALL=1 to skip this entire script.
|
|
24
|
+
* Example: SEC_GATE_SKIP_POSTINSTALL=1 npm install -g sec-gate
|
|
25
|
+
*
|
|
26
|
+
* SOURCE: https://github.com/SUNDRAMBHARDWAJ/sec-gate
|
|
10
27
|
*/
|
|
11
28
|
|
|
12
|
-
|
|
13
|
-
|
|
29
|
+
// Opt-out: allow users/CI systems to skip postinstall entirely
|
|
30
|
+
if (process.env.SEC_GATE_SKIP_POSTINSTALL === '1') {
|
|
31
|
+
console.log('sec-gate: postinstall skipped (SEC_GATE_SKIP_POSTINSTALL=1)');
|
|
32
|
+
process.exit(0);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const fs = require('fs');
|
|
36
|
+
const path = require('path');
|
|
14
37
|
const https = require('https');
|
|
38
|
+
const crypto = require('crypto');
|
|
15
39
|
const { execSync, execFileSync } = require('child_process');
|
|
16
40
|
|
|
17
41
|
const BIN_DIR = path.join(__dirname, '..', 'vendor-bin');
|
|
@@ -21,7 +45,9 @@ const platform = process.platform; // darwin, linux, win32
|
|
|
21
45
|
const arch = process.arch; // x64, arm64
|
|
22
46
|
|
|
23
47
|
// ─────────────────────────────────────────────────────────
|
|
24
|
-
// 1
|
|
48
|
+
// [1/3] OSV-Scanner binary download
|
|
49
|
+
// Source: https://github.com/google/osv-scanner/releases/
|
|
50
|
+
// No data is sent — we only download a binary from GitHub releases.
|
|
25
51
|
// ─────────────────────────────────────────────────────────
|
|
26
52
|
const OSV_VERSION = 'v2.3.5';
|
|
27
53
|
|
|
@@ -59,47 +85,55 @@ async function installOsvScanner() {
|
|
|
59
85
|
const dest = path.join(BIN_DIR, `osv-scanner${ext}`);
|
|
60
86
|
|
|
61
87
|
if (fs.existsSync(dest)) {
|
|
62
|
-
console.log('sec-gate [1/3]: osv-scanner already present');
|
|
88
|
+
console.log('sec-gate [1/3]: osv-scanner already present, skipping download');
|
|
63
89
|
return;
|
|
64
90
|
}
|
|
65
91
|
|
|
66
92
|
const url = osvDownloadUrl();
|
|
67
|
-
console.log(`sec-gate [1/3]: downloading osv-scanner
|
|
93
|
+
console.log(`sec-gate [1/3]: downloading osv-scanner ${OSV_VERSION}`);
|
|
94
|
+
console.log(` source: ${url}`);
|
|
68
95
|
|
|
69
96
|
try {
|
|
70
97
|
await downloadFile(url, dest);
|
|
71
98
|
fs.chmodSync(dest, 0o755);
|
|
72
|
-
|
|
99
|
+
|
|
100
|
+
// Print a SHA256 fingerprint so security-conscious users can verify
|
|
101
|
+
const hash = crypto.createHash('sha256').update(fs.readFileSync(dest)).digest('hex');
|
|
102
|
+
console.log(`sec-gate [1/3]: osv-scanner ready (sha256: ${hash})`);
|
|
103
|
+
console.log(` verify at: https://github.com/google/osv-scanner/releases/tag/${OSV_VERSION}`);
|
|
73
104
|
} catch (err) {
|
|
74
105
|
console.warn(`sec-gate [1/3]: WARNING — osv-scanner download failed: ${err.message}`);
|
|
75
|
-
console.warn(' Node/pnpm SCA will be skipped
|
|
106
|
+
console.warn(' Node/pnpm SCA will be skipped. Re-run: npm i -g sec-gate');
|
|
76
107
|
}
|
|
77
108
|
}
|
|
78
109
|
|
|
79
110
|
// ─────────────────────────────────────────────────────────
|
|
80
|
-
// 2
|
|
111
|
+
// [2/3] govulncheck via `go install`
|
|
112
|
+
// Only installs if Go is available on this machine.
|
|
113
|
+
// Source: https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck
|
|
81
114
|
// ─────────────────────────────────────────────────────────
|
|
82
115
|
function installGovulncheck() {
|
|
83
116
|
const ext = platform === 'win32' ? '.exe' : '';
|
|
84
117
|
const dest = path.join(BIN_DIR, `govulncheck${ext}`);
|
|
85
118
|
|
|
86
119
|
if (fs.existsSync(dest)) {
|
|
87
|
-
console.log('sec-gate [2/3]: govulncheck already present');
|
|
120
|
+
console.log('sec-gate [2/3]: govulncheck already present, skipping install');
|
|
88
121
|
return;
|
|
89
122
|
}
|
|
90
123
|
|
|
124
|
+
// Check if Go is available — skip silently if not
|
|
91
125
|
try {
|
|
92
|
-
|
|
126
|
+
execFileSync('go', ['version'], { stdio: 'ignore' });
|
|
93
127
|
} catch {
|
|
94
|
-
console.
|
|
95
|
-
console.
|
|
128
|
+
console.log('sec-gate [2/3]: Go not found — skipping govulncheck install');
|
|
129
|
+
console.log(' To enable Go SCA: install Go (https://go.dev/dl/) and re-run: npm i -g sec-gate');
|
|
96
130
|
return;
|
|
97
131
|
}
|
|
98
132
|
|
|
99
133
|
try {
|
|
100
|
-
console.log('sec-gate [2/3]: installing govulncheck
|
|
101
|
-
const gopath =
|
|
102
|
-
|
|
134
|
+
console.log('sec-gate [2/3]: installing govulncheck via `go install golang.org/x/vuln/cmd/govulncheck@latest`');
|
|
135
|
+
const gopath = execFileSync('go', ['env', 'GOPATH'], { encoding: 'utf8' }).trim();
|
|
136
|
+
execFileSync('go', ['install', 'golang.org/x/vuln/cmd/govulncheck@latest'], { stdio: 'inherit' });
|
|
103
137
|
|
|
104
138
|
const goSrc = path.join(gopath, 'bin', `govulncheck${ext}`);
|
|
105
139
|
if (fs.existsSync(goSrc)) {
|
|
@@ -114,7 +148,9 @@ function installGovulncheck() {
|
|
|
114
148
|
}
|
|
115
149
|
|
|
116
150
|
// ─────────────────────────────────────────────────────────
|
|
117
|
-
// 3
|
|
151
|
+
// [3/3] Auto-install pre-commit hook in the current git repo
|
|
152
|
+
// Backs up any existing hook before writing.
|
|
153
|
+
// Skipped silently if not inside a git repo.
|
|
118
154
|
// ─────────────────────────────────────────────────────────
|
|
119
155
|
const HOOK_MARKER = '# installed-by: sec-gate';
|
|
120
156
|
|
|
@@ -147,13 +183,13 @@ function autoInstallHook() {
|
|
|
147
183
|
let repoRoot;
|
|
148
184
|
|
|
149
185
|
try {
|
|
150
|
-
repoRoot =
|
|
186
|
+
repoRoot = execFileSync('git', ['rev-parse', '--show-toplevel'], {
|
|
151
187
|
encoding: 'utf8',
|
|
152
188
|
stdio: ['ignore', 'pipe', 'ignore']
|
|
153
189
|
}).trim();
|
|
154
190
|
} catch {
|
|
155
|
-
|
|
156
|
-
console.log('sec-gate
|
|
191
|
+
console.log('sec-gate [3/3]: not inside a git repo — skipping hook install');
|
|
192
|
+
console.log(' Run `sec-gate install` inside your project to install the hook.');
|
|
157
193
|
return;
|
|
158
194
|
}
|
|
159
195
|
|
|
@@ -162,15 +198,12 @@ function autoInstallHook() {
|
|
|
162
198
|
|
|
163
199
|
fs.mkdirSync(hookDir, { recursive: true });
|
|
164
200
|
|
|
165
|
-
// Already installed by us — nothing to do
|
|
166
201
|
if (fs.existsSync(hookPath)) {
|
|
167
202
|
const existing = fs.readFileSync(hookPath, 'utf8');
|
|
168
203
|
if (existing.includes(HOOK_MARKER)) {
|
|
169
204
|
console.log('sec-gate [3/3]: pre-commit hook already installed');
|
|
170
205
|
return;
|
|
171
206
|
}
|
|
172
|
-
|
|
173
|
-
// Back up a hook that belongs to something else
|
|
174
207
|
const backup = `${hookPath}.sec-gate.bak`;
|
|
175
208
|
fs.copyFileSync(hookPath, backup);
|
|
176
209
|
console.log(`sec-gate [3/3]: backed up existing hook → ${backup}`);
|
|
@@ -184,7 +217,8 @@ function autoInstallHook() {
|
|
|
184
217
|
// Main
|
|
185
218
|
// ─────────────────────────────────────────────────────────
|
|
186
219
|
async function main() {
|
|
187
|
-
console.log('\nsec-gate: setting up
|
|
220
|
+
console.log('\nsec-gate: setting up bundled scanners...');
|
|
221
|
+
console.log(' (set SEC_GATE_SKIP_POSTINSTALL=1 to skip this)\n');
|
|
188
222
|
await installOsvScanner();
|
|
189
223
|
installGovulncheck();
|
|
190
224
|
autoInstallHook();
|
|
@@ -192,7 +226,7 @@ async function main() {
|
|
|
192
226
|
}
|
|
193
227
|
|
|
194
228
|
main().catch((err) => {
|
|
195
|
-
// Never fail the install — degraded mode is
|
|
229
|
+
// Never fail the npm install itself — degraded mode is better than blocked install
|
|
196
230
|
console.warn('sec-gate postinstall warning:', err.message);
|
|
197
231
|
process.exit(0);
|
|
198
232
|
});
|