diff --git a/.github/workflows/cve.yml b/.github/workflows/cve.yml new file mode 100644 index 0000000..fec7b8c --- /dev/null +++ b/.github/workflows/cve.yml @@ -0,0 +1,41 @@ +# cve: known vulnerabilities in what this repository pins. Runs on main after each merge, on each +# pull request, and every Monday, so an advisory published after a merge still turns main red. +# +# - osv: OSV-Scanner reads every lock file (the labs' Cargo.lock, package-lock.json) against +# osv.dev. An advisory with no fix the lab can take is listed, with its reason and an expiry +# date, in that lab's osv-scanner.toml. +# - node: is-my-node-vulnerable checks the Node that labs/gleam-website gives against Node.js's own +# advisories (nodejs/security-wg). Those advisories lag the Node.js blog, so the lab also states +# its minimum Node in checks.node-version, which ci.yml builds. +name: cve + +on: + push: + branches: [main] + pull_request: + schedule: + - cron: "17 6 * * 1" + workflow_dispatch: + +permissions: + contents: read + +jobs: + osv: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@v7 + - uses: DeterminateSystems/nix-installer-action@v23 + - name: OSV-Scanner over every lock file + run: nix run nixpkgs#osv-scanner -- scan source --recursive . + + node: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@v7 + - uses: DeterminateSystems/nix-installer-action@v23 + - name: is-my-node-vulnerable, on the Node of labs/gleam-website + working-directory: labs/gleam-website + run: nix develop --no-update-lock-file --command bash -c 'node --version && npx --yes is-my-node-vulnerable@1.6.1' diff --git a/labs/gleam-website/README.md b/labs/gleam-website/README.md index 0374269..8c35bb7 100644 --- a/labs/gleam-website/README.md +++ b/labs/gleam-website/README.md @@ -43,7 +43,7 @@ Lustre application, `src//prerender.gleam` prints the first render as `dist | Type | Program | | :--------- | :-----: | | Language | [Gleam 1.19](https://gleam.run/) on the JavaScript target; sites use [Lustre](https://lustre.build) from Hex | -| Runtime | [Node.js 24](https://nodejs.org/) (`gleam test`, `gleam run` for the prerender) | +| Runtime | [Node.js 24.22.1](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases), the official nodejs.org build pinned by sha256 in `nodejs-bin.nix` until nixpkgs ships it (`gleam test`, `gleam run` for the prerender); `checks.node-version` fails below 24.22.1 | | Bundler | [esbuild](https://esbuild.github.io/) | | Scripting | [just](https://github.com/casey/just), python 3 | | Reuse | `lib..tools`, `packages..{gleam, esbuild}`, `checks..{smoke, versions}` | diff --git a/labs/gleam-website/flake.nix b/labs/gleam-website/flake.nix index 26b79ba..bbcbb2f 100644 --- a/labs/gleam-website/flake.nix +++ b/labs/gleam-website/flake.nix @@ -13,9 +13,24 @@ # The toolchain of picasso's own site/ (Gleam + Lustre, bundled by esbuild). A site pins its # Hex packages by checksum in its manifest.toml; everything else comes from here. + nodeFor = pkgs: pkgs.callPackage ./nodejs-bin.nix { }; + + # The October 2026 security release (nodejs.org/en/blog/vulnerability/october-2026-security-releases): + # the scanners' databases lag the advisory, so the minimum is stated here and checked in CI. + nodeVersionFor = pkgs: + let node = nodeFor pkgs; in + assert lib.assertMsg (lib.versionAtLeast node.version "24.22.1") + "gleam-website: node ${node.version} is below 24.22.1, the October 2026 security release"; + pkgs.runCommand "gleam-website-node-version" { nativeBuildInputs = [ node ]; } '' + node --version | tee "$out" + ''; + toolsFor = pkgs: with pkgs; [ gleam - nodejs # gleam test, gleam run (the prerender) and the bundle check run on node + # gleam test, gleam run (the prerender) and the bundle check run on node: the official + # 24.22.1 build (nodejs-bin.nix), the October 2026 security release, until nixpkgs ships it. + # Only this list gets it: an overlay of pkgs.nodejs would rebuild erlang and webkitgtk. + (nodeFor pkgs) esbuild just python3 # the small generators and checks a site keeps next to its Gleam code @@ -89,6 +104,7 @@ checks = forAll (pkgs: { lab-json = labCardFor pkgs; + node-version = nodeVersionFor pkgs; versions = self.packages.${pkgs.stdenv.hostPlatform.system}.versions; smoke = self.packages.${pkgs.stdenv.hostPlatform.system}.smoke; }); diff --git a/labs/gleam-website/lab.json b/labs/gleam-website/lab.json index 702091f..574414d 100644 --- a/labs/gleam-website/lab.json +++ b/labs/gleam-website/lab.json @@ -1,4 +1,4 @@ { "summary": "Gleam on the JavaScript target, node, esbuild, just: static sites in picasso's style", - "headline": ["gleam", "nodejs", "esbuild", "just"] + "headline": ["gleam", "esbuild", "just"] } diff --git a/labs/gleam-website/nodejs-bin.nix b/labs/gleam-website/nodejs-bin.nix new file mode 100644 index 0000000..2ca9589 --- /dev/null +++ b/labs/gleam-website/nodejs-bin.nix @@ -0,0 +1,41 @@ +# Node.js 24.22.1, the official build from nodejs.org, in place of nixpkgs' nodejs until nixpkgs +# ships it: 24.22.1 is the October 2026 security release (Brotli RCE, TLS hostname bypass, +# nodejs.org/en/blog/vulnerability/october-2026-security-releases), and nixos-unstable is still on +# 24.21.0 (2026-10-22). The hashes are the release's SHASUMS256.txt. Drop this file, and the +# overlay in flake.nix, once `nix flake update` brings nodejs >= 24.22.1. +{ lib, stdenv, fetchurl, autoPatchelfHook }: + +let + version = "24.22.1"; + builds = { + x86_64-linux = { arch = "linux-x64"; sha256 = "6c172a9ab6718f7b801fb5a7bd486af2ee5e32758086a04b84fcce2aa77095e6"; }; + aarch64-linux = { arch = "linux-arm64"; sha256 = "dbabf7a1cbf947e6059ffad2c27b80041db97dea1e553b62afdee7f13fca336e"; }; + aarch64-darwin = { arch = "darwin-arm64"; sha256 = "654ba79de6155647e22321932b45f2a1ccb705976cc337c9b8e278beb085a628"; }; + }; + build = builds.${stdenv.hostPlatform.system} or (throw "nodejs-bin: no official build for ${stdenv.hostPlatform.system}"); +in +stdenv.mkDerivation { + pname = "nodejs"; + inherit version; + src = fetchurl { + url = "https://nodejs.org/dist/v${version}/node-v${version}-${build.arch}.tar.xz"; + inherit (build) sha256; + }; + nativeBuildInputs = lib.optionals stdenv.hostPlatform.isLinux [ autoPatchelfHook ]; + buildInputs = lib.optionals stdenv.hostPlatform.isLinux [ stdenv.cc.cc.lib ]; + dontConfigure = true; + dontBuild = true; + installPhase = '' + runHook preInstall + mkdir -p $out + cp -r bin include lib share $out/ + runHook postInstall + ''; + meta = { + description = "Node.js ${version}, the official nodejs.org build"; + homepage = "https://nodejs.org"; + license = lib.licenses.mit; + mainProgram = "node"; + platforms = builtins.attrNames builds; + }; +} diff --git a/labs/ptbr-pdf/osv-scanner.toml b/labs/ptbr-pdf/osv-scanner.toml new file mode 100644 index 0000000..6f041e2 --- /dev/null +++ b/labs/ptbr-pdf/osv-scanner.toml @@ -0,0 +1,44 @@ +# OSV-Scanner exceptions for this lab's Cargo.lock (.github/workflows/cve.yml). Each entry is an +# advisory that has no fix this lab can take: the crate comes in through typst, and only a typst +# update moves it. ignoreUntil makes the scan fail again on that date, so each one is read again. +# Read from api.osv.dev on 2026-10-22. + +[[IgnoredVulns]] +id = "RUSTSEC-2026-0194" +ignoreUntil = 2027-01-22T00:00:00Z +reason = "quick-xml 0.38.4, quadratic time on duplicate attributes. It comes from typst's citationberg and plist; the lock already has 0.42.0 for the rest. Whether to-pdf ever hands it untrusted XML was not checked. Fixed in 0.41.0: drop this when typst updates." + +[[IgnoredVulns]] +id = "RUSTSEC-2026-0195" +ignoreUntil = 2027-01-22T00:00:00Z +reason = "quick-xml 0.38.4, unbounded namespace allocation in NsReader. Same path and same fix as RUSTSEC-2026-0194." + +[[IgnoredVulns]] +id = "RUSTSEC-2025-0141" +ignoreUntil = 2027-01-22T00:00:00Z +reason = "bincode is unmaintained (no known flaw); it comes from typst's dependencies." + +[[IgnoredVulns]] +id = "RUSTSEC-2024-0436" +ignoreUntil = 2027-01-22T00:00:00Z +reason = "paste is unmaintained (no known flaw); it comes from typst's dependencies." + +[[IgnoredVulns]] +id = "RUSTSEC-2026-0206" +ignoreUntil = 2027-01-22T00:00:00Z +reason = "rustybuzz is unmaintained (no known flaw); typst's text shaping." + +[[IgnoredVulns]] +id = "RUSTSEC-2026-0192" +ignoreUntil = 2027-01-22T00:00:00Z +reason = "ttf-parser is unmaintained (no known flaw); typst's font parsing, of the six embedded fonts." + +[[IgnoredVulns]] +id = "RUSTSEC-2024-0449" +ignoreUntil = 2027-01-22T00:00:00Z +reason = "unsafe-libyaml is unmaintained (no known flaw); it comes from typst's dependencies." + +[[IgnoredVulns]] +id = "RUSTSEC-2024-0320" +ignoreUntil = 2027-01-22T00:00:00Z +reason = "yaml-rust is unmaintained (no known flaw); it comes from typst's dependencies."