@theoptimalpartner/npm-security-kit 2.0.0-beta.0 → 2.0.0-beta.2
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/CHANGELOG.md +6 -2
- package/README.md +10 -7
- package/package.json +1 -1
- package/src/init.js +26 -6
package/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,11 @@ Cambios del paquete `@theoptimalpartner/npm-security-kit`. Formato basado en
|
|
|
6
6
|
## [2.0.0] - sin publicar
|
|
7
7
|
|
|
8
8
|
Reescritura completa. La v2 es una CLI de Node sin dependencias que corre en el pipeline **antes de `npm ci`**.
|
|
9
|
-
Sale primero como `2.0.0-beta.
|
|
9
|
+
Sale primero como beta (`2.0.0-beta.N`), con el dist-tag `beta`. Desde la `2.0.0-beta.1`, el step del pipeline y
|
|
10
|
+
`init` usan `npx --yes --min-release-age=0`: `npx` no aplica `min-release-age-exclude` y, sin el flag, una versión
|
|
11
|
+
nueva del kit no se puede usar hasta cumplir 7 días. Desde la `2.0.0-beta.2`, `init` propone el Node que ya usa el
|
|
12
|
+
repo si es una LTS con soporte (la imagen del step de ejemplo y, si falta, `engines.node`), en vez de la LTS más
|
|
13
|
+
nueva: un `engines.node` más alto que el Node del repo rompe su `npm ci` con `engine-strict`.
|
|
10
14
|
|
|
11
15
|
### BREAKING
|
|
12
16
|
|
|
@@ -37,7 +41,7 @@ Sale primero como `2.0.0-beta.0`, con el dist-tag `beta`.
|
|
|
37
41
|
`scripts/security-check.sh`, `.husky/` (y el `"prepare": "husky install"`), los scripts `security:*` del
|
|
38
42
|
`package.json` y el `SECURITY.md` generado.
|
|
39
43
|
2. Si la v1 reemplazó el `bitbucket-pipelines.yml`, recuperar el del repo desde git.
|
|
40
|
-
3. Correr `npx --yes @theoptimalpartner/npm-security-kit@2.0.0 init` y seguir los pasos que imprime (README).
|
|
44
|
+
3. Correr `npx --yes --min-release-age=0 @theoptimalpartner/npm-security-kit@2.0.0 init` y seguir los pasos que imprime (README).
|
|
41
45
|
|
|
42
46
|
## [1.0.2] y anteriores
|
|
43
47
|
|
package/README.md
CHANGED
|
@@ -57,7 +57,7 @@ definitions:
|
|
|
57
57
|
- npm
|
|
58
58
|
script:
|
|
59
59
|
# Antes de instalar: malware, vulnerabilidades, Node, .npmrc, install scripts, Dockerfiles
|
|
60
|
-
- npx --yes @theoptimalpartner/npm-security-kit@2.0.0 check
|
|
60
|
+
- npx --yes --min-release-age=0 @theoptimalpartner/npm-security-kit@2.0.0 check
|
|
61
61
|
- npm ci # con strict-allow-scripts, los scripts no aprobados cortan acá
|
|
62
62
|
- npm audit signatures
|
|
63
63
|
- npm run build
|
|
@@ -73,10 +73,13 @@ pipelines:
|
|
|
73
73
|
|
|
74
74
|
- **Antes de `npm ci`:** `npm audit` funciona solo con el lockfile, así que el malware se detecta antes de que
|
|
75
75
|
corra su `postinstall`.
|
|
76
|
-
- **Versión fija** (`@2.0.0`): subir la política en un repo es un cambio visible en su PR.
|
|
77
|
-
|
|
76
|
+
- **Versión fija** (`@2.0.0`): subir la política en un repo es un cambio visible en su PR.
|
|
77
|
+
- **`--min-release-age=0` solo para `npx`:** `npx` no aplica `min-release-age-exclude` (npm 11.19.1 lo aplica al
|
|
78
|
+
instalar, no al resolver el paquete de `npx`). Sin el flag, dentro de un repo con `min-release-age=7` una versión
|
|
79
|
+
nueva del kit no se puede usar hasta cumplir 7 días (`ETARGET … with a date before`). Afecta solo al kit: la
|
|
80
|
+
versión va fija y no tiene dependencias. El `npm ci` que sigue aplica los 7 días como siempre.
|
|
78
81
|
- **`npm audit signatures`** va después de `npm ci` porque necesita `node_modules`.
|
|
79
|
-
- Para guardar el resultado como artefacto: `npx --yes @theoptimalpartner/npm-security-kit@2.0.0 check --json > npm-security-kit.json`.
|
|
82
|
+
- Para guardar el resultado como artefacto: `npx --yes --min-release-age=0 @theoptimalpartner/npm-security-kit@2.0.0 check --json > npm-security-kit.json`.
|
|
80
83
|
|
|
81
84
|
### Dockerfile
|
|
82
85
|
|
|
@@ -95,11 +98,11 @@ Si el `.dockerignore` excluye el `.npmrc` (por ejemplo con `.*`), agregar `!.npm
|
|
|
95
98
|
Una vez por repo, en una rama:
|
|
96
99
|
|
|
97
100
|
```bash
|
|
98
|
-
npx --yes @theoptimalpartner/npm-security-kit@2.0.0 init --dry-run
|
|
101
|
+
npx --yes --min-release-age=0 @theoptimalpartner/npm-security-kit@2.0.0 init --dry-run
|
|
99
102
|
```
|
|
100
103
|
|
|
101
104
|
```bash
|
|
102
|
-
npx --yes @theoptimalpartner/npm-security-kit@2.0.0 init
|
|
105
|
+
npx --yes --min-release-age=0 @theoptimalpartner/npm-security-kit@2.0.0 init
|
|
103
106
|
```
|
|
104
107
|
|
|
105
108
|
`init`:
|
|
@@ -116,7 +119,7 @@ Después: revisar el diff, aprobar o negar los install scripts, aplicar el step
|
|
|
116
119
|
### En local
|
|
117
120
|
|
|
118
121
|
```bash
|
|
119
|
-
npx --yes @theoptimalpartner/npm-security-kit@2.0.0 check
|
|
122
|
+
npx --yes --min-release-age=0 @theoptimalpartner/npm-security-kit@2.0.0 check
|
|
120
123
|
```
|
|
121
124
|
|
|
122
125
|
No se instala como devDependency ni usa husky: el `.npmrc` protege el `npm install` local y el pipeline es el
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theoptimalpartner/npm-security-kit",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.2",
|
|
4
4
|
"description": "Revisa el lockfile antes de npm ci: malware, vulnerabilidades, versión de Node, .npmrc, install scripts y Dockerfiles",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/init.js
CHANGED
|
@@ -77,6 +77,27 @@ export function mergePackageJson(text, policy, nodeMajor) {
|
|
|
77
77
|
return { text: finalNewline ? `${out}${eol}` : out, changes };
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
// El Node que init propone (engines.node y la imagen del step de ejemplo): el que ya usa el repo si es
|
|
81
|
+
// de una LTS con soporte, para que adoptar el kit no obligue a cambiar de Node. engines.node toma la
|
|
82
|
+
// línea más baja en uso (con engine-strict, un ">=" más alto rompe el npm ci de esa línea), y la imagen,
|
|
83
|
+
// la versión exacta del pipeline. Sin eso, la release LTS recomendada.
|
|
84
|
+
export function repoNode(ctx, cal) {
|
|
85
|
+
const recommended = cal.recommended ?? null;
|
|
86
|
+
let major = null;
|
|
87
|
+
let image = null;
|
|
88
|
+
for (const pin of nodeVersionCheck.findPins(ctx)) {
|
|
89
|
+
const r = nodeVersionCheck.resolvePin(pin, cal);
|
|
90
|
+
if (r.major === undefined || r.major === null || r.latest) continue;
|
|
91
|
+
if (!['active', 'maintenance'].includes(cal.phaseOf(r.major))) continue;
|
|
92
|
+
if (major === null || r.major < major) major = r.major;
|
|
93
|
+
if (!image && pin.file === 'bitbucket-pipelines.yml' && pin.kind === 'docker' && r.exact) image = r.exact;
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
major: major ?? (recommended ? parseVersion(recommended)[0] : null),
|
|
97
|
+
image: image ?? recommended,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
80
101
|
export function pipelineStep(kitVersion, nodeVersion) {
|
|
81
102
|
return `- step: &test
|
|
82
103
|
name: Test (supply chain + build)
|
|
@@ -85,7 +106,7 @@ export function pipelineStep(kitVersion, nodeVersion) {
|
|
|
85
106
|
- npm
|
|
86
107
|
script:
|
|
87
108
|
# Antes de instalar: malware, vulnerabilidades, Node, .npmrc, install scripts, Dockerfiles
|
|
88
|
-
- npx --yes ${PACKAGE}@${kitVersion} check
|
|
109
|
+
- npx --yes --min-release-age=0 ${PACKAGE}@${kitVersion} check
|
|
89
110
|
- npm ci
|
|
90
111
|
- npm audit signatures
|
|
91
112
|
- npm run build
|
|
@@ -147,15 +168,14 @@ export async function runInit(ctx, { dryRun = false, stdout = process.stdout, co
|
|
|
147
168
|
} catch (error) {
|
|
148
169
|
cal = { error };
|
|
149
170
|
}
|
|
150
|
-
const
|
|
151
|
-
const nodeMajor = nodeVersion ? parseVersion(nodeVersion)[0] : null;
|
|
171
|
+
const node = cal.error ? { major: null, image: null } : repoNode(ctx, cal);
|
|
152
172
|
|
|
153
173
|
say(paint(2, `npm-security-kit ${ctx.kitVersion} · init${dryRun ? ' --dry-run' : ''} · ${ctx.dir}`));
|
|
154
174
|
|
|
155
175
|
// 1. .npmrc y package.json
|
|
156
176
|
const npmrcBefore = ctx.readFile('.npmrc');
|
|
157
177
|
const npmrc = mergeNpmrc(npmrcBefore, ctx.policy);
|
|
158
|
-
const pkg = mergePackageJson(pkgText, ctx.policy,
|
|
178
|
+
const pkg = mergePackageJson(pkgText, ctx.policy, node.major);
|
|
159
179
|
if (npmrc.changes.length) files['.npmrc'] = npmrc.text;
|
|
160
180
|
if (pkg.changes.length) files['package.json'] = pkg.text;
|
|
161
181
|
|
|
@@ -207,7 +227,7 @@ export async function runInit(ctx, { dryRun = false, stdout = process.stdout, co
|
|
|
207
227
|
} else {
|
|
208
228
|
say(` ${pipeline === null ? 'No hay bitbucket-pipelines.yml. ' : ''}Agregar el kit en el step de test, ANTES de npm ci, y correrlo solo en los PR a ramas que despliegan:`);
|
|
209
229
|
say();
|
|
210
|
-
for (const line of pipelineStep(ctx.kitVersion,
|
|
230
|
+
for (const line of pipelineStep(ctx.kitVersion, node.image ?? '<versión LTS>').split('\n')) say(` ${line}`);
|
|
211
231
|
}
|
|
212
232
|
|
|
213
233
|
// 4. Dockerfiles (no se editan)
|
|
@@ -227,7 +247,7 @@ export async function runInit(ctx, { dryRun = false, stdout = process.stdout, co
|
|
|
227
247
|
dryRun ? 'Correr init sin --dry-run.' : 'Revisar el diff: git diff .npmrc package.json',
|
|
228
248
|
'Aprobar o negar los install scripts pendientes.',
|
|
229
249
|
'Agregar el step al pipeline y corregir los Dockerfiles.',
|
|
230
|
-
`Correr el chequeo completo: npx --yes ${PACKAGE}@${ctx.kitVersion} check`,
|
|
250
|
+
`Correr el chequeo completo: npx --yes --min-release-age=0 ${PACKAGE}@${ctx.kitVersion} check`,
|
|
231
251
|
];
|
|
232
252
|
steps.forEach((s, i) => say(` ${i + 1}. ${s}`));
|
|
233
253
|
|