Skip to content

Commit f03c359

Browse files
feat: add vex generator (#1537)
* feat: add vex generator * chore: bump node versions * fix: update validator function
1 parent b2bb305 commit f03c359

25 files changed

Lines changed: 3841 additions & 8 deletions

.github/workflows/generate-vex.yml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
name: "Generate VEX document"
2+
3+
on:
4+
workflow_run:
5+
workflows:
6+
- "Update core index.json"
7+
- "Update deps index.json"
8+
- "Update npm index.json"
9+
types:
10+
- completed
11+
workflow_dispatch:
12+
push:
13+
branches:
14+
- main
15+
paths:
16+
- 'vuln/core/index.json'
17+
- 'vuln/npm/index.json'
18+
- 'vuln/deps/index.json'
19+
- 'tools/vex/**'
20+
21+
concurrency:
22+
group: generate-vex
23+
cancel-in-progress: true
24+
25+
permissions:
26+
contents: write
27+
pull-requests: write
28+
29+
jobs:
30+
generate-vex:
31+
runs-on: ubuntu-latest
32+
steps:
33+
- name: Harden Runner
34+
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
35+
with:
36+
egress-policy: audit
37+
38+
- name: Checkout repository
39+
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
40+
with:
41+
persist-credentials: false
42+
43+
- name: Setup Go
44+
uses: actions/setup-go@v5
45+
with:
46+
go-version: '1.23.x'
47+
48+
- name: Generate VEX document
49+
working-directory: tools/vex
50+
run: |
51+
go run .
52+
53+
- name: Detect changes
54+
id: detect
55+
run: |
56+
if git diff --quiet node.openvex.json; then
57+
echo "no_changes=true" >> $GITHUB_OUTPUT
58+
else
59+
echo "no_changes=false" >> $GITHUB_OUTPUT
60+
fi
61+
62+
- name: Create Pull Request
63+
if: steps.detect.outputs.no_changes == 'false'
64+
uses: gr2m/create-or-update-pull-request-action@77596e3166f328b24613f7082ab30bf2d93079d5
65+
env:
66+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
67+
with:
68+
commit-message: 'vex: regenerate node.openvex.json'
69+
title: regenerate node.openvex.json
70+
body: 'Automated regeneration of node.openvex.json after vulnerability index update. cc: @nodejs/security-wg'
71+
assignees: ${{ github.actor }}
72+
labels: security-wg-agenda
73+
branch: regenerate-vex
74+
update-pull-request-title-and-body: true
75+
76+
- name: No changes summary
77+
if: steps.detect.outputs.no_changes == 'true'
78+
run: echo "No changes to node.openvex.json; skipping PR creation."

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
strategy:
1616
fail-fast: false
1717
matrix:
18-
node-version: [18.x, 20.x, 22.x]
18+
node-version: [20.x, 22.x, '24.x']
1919
os: [ubuntu-latest]
2020
runs-on: ${{ matrix.os }}
2121
steps:

.github/workflows/update-core-index.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727

2828
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
2929
with:
30-
node-version: 18
30+
node-version-file: '.nvmrc'
3131

3232
- name: Install deps
3333
run: npm ci
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: "Update deps index.json"
2+
on:
3+
workflow_dispatch:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'vuln/deps/*.json'
9+
- '!vuln/deps/index.json'
10+
11+
permissions:
12+
contents: write
13+
pull-requests: write
14+
15+
jobs:
16+
stale:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Harden Runner
20+
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
21+
with:
22+
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
23+
24+
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
25+
with:
26+
persist-credentials: false
27+
28+
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
29+
with:
30+
node-version-file: '.nvmrc'
31+
32+
- name: Install deps
33+
run: npm ci
34+
35+
- name: Update deps index.json
36+
run: |
37+
npm run create-deps-index
38+
39+
- name: Create Pull Request
40+
uses: gr2m/create-or-update-pull-request-action@77596e3166f328b24613f7082ab30bf2d93079d5
41+
env:
42+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43+
with:
44+
commit-message: 'vuln: update deps index.json'
45+
title: update deps index.json
46+
body: 'update deps index.json. cc: @nodejs/security-wg'
47+
assignees: ${{ github.actor }}
48+
labels: security-wg-agenda
49+
branch: deps-index-updated
50+
update-pull-request-title-and-body: true

.github/workflows/update-npm-index.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727

2828
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
2929
with:
30-
node-version: 18
30+
node-version-file: '.nvmrc'
3131

3232
- name: Install deps
3333
run: npm ci

.github/workflows/validate-vulnerability.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
- name: Use Node.js
2525
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
2626
with:
27-
node-version: 18
27+
node-version-file: '.nvmrc'
2828

2929
- name: Install deps
3030
run: npm ci

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
22

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
"test": "node --test",
66
"validate": "node tools/vuln_valid",
77
"create-npm-index": "node tools/create_index/create_npm_index.js",
8-
"create-core-index": "node tools/create_index/create_core_index.js"
8+
"create-core-index": "node tools/create_index/create_core_index.js",
9+
"create-deps-index": "node tools/create_index/create_deps_index.js"
910
},
1011
"keywords": [],
1112
"author": "",
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
const fs = require('node:fs')
2+
const path = require('node:path')
3+
4+
const depsVulnerabilitiesPath = path.join(__dirname, '../../vuln/deps/')
5+
6+
// Valid justification values from OpenVEX spec v0.2.0
7+
// See: https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md#status-justifications
8+
const validJustifications = [
9+
'component_not_present',
10+
'vulnerable_code_not_present',
11+
'vulnerable_code_not_in_execute_path',
12+
'vulnerable_code_cannot_be_controlled_by_adversary',
13+
'inline_mitigations_already_exist'
14+
]
15+
16+
let vuln = {}
17+
18+
function createDepsIndex() {
19+
const files = fs.readdirSync(depsVulnerabilitiesPath)
20+
getVulnDirectoryContents(files)
21+
writeIndex(vuln)
22+
}
23+
24+
function getVulnDirectoryContents(files) {
25+
for (const file of files) {
26+
const filename = file.slice(0, file.toString().indexOf('.json'))
27+
if (filename !== 'index') {
28+
const data = fs.readFileSync(depsVulnerabilitiesPath + file)
29+
const json = JSON.parse(data)
30+
31+
if (!json.reason) {
32+
throw new Error(`Missing 'reason' field in ${file}`)
33+
}
34+
35+
if (!validJustifications.includes(json.reason)) {
36+
throw new Error(
37+
`Invalid justification '${json.reason}' in ${file}. ` +
38+
`Valid values are: ${validJustifications.join(', ')}`
39+
)
40+
}
41+
42+
createVulnObject(filename, json)
43+
}
44+
}
45+
}
46+
47+
function createVulnObject(identifier, json) {
48+
vuln[identifier] = json
49+
}
50+
51+
function writeIndex(data) {
52+
fs.writeFileSync(depsVulnerabilitiesPath + 'index.json', JSON.stringify(data, null, 2))
53+
console.log('Successfully wrote ' + depsVulnerabilitiesPath + 'index.json for deps vulnerabilities.')
54+
}
55+
56+
createDepsIndex()

tools/vex/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node-vex-generator

0 commit comments

Comments
 (0)