Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .cargo/audit.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# SPDX-License-Identifier: MPL-2.0
# cargo-audit configuration for VeriSimDB.
# Run: cargo audit (CI: rustsec/audit-check in .github/workflows/rust-ci.yml)
#
# Keep this list in step with `deny.toml` `[advisories].ignore`. They are
# separate tools with separate config and they resolve the dependency graph
# differently — cargo-audit reads Cargo.lock directly, cargo-deny resolves
# features — so the same advisory can surface in one and not the other. An
# entry justified for one is justified for both; edit the two files together.
#
# Policy: an entry is only permitted when there is no version of this tree
# that resolves the advisory. "We haven't got round to it" is not a reason —
# bump the dependency instead. Re-check every entry when its blocking upstream
# publishes a release.

[advisories]
ignore = [
# quick-xml 0.37.5 — two DoS advisories, both fixed upstream in 0.41.0.
# Reached ONLY through oxigraph → {oxrdfxml, sparesults}. oxigraph 0.5.9 is
# the latest published release and still requires quick-xml ^0.37, so no
# resolution of this lockfile avoids it.
# Exposure: verisim-graph's `oxigraph-backend` feature is NOT in `default`,
# so a stock build never links quick-xml.
# REMOVE WHEN: oxigraph publishes a release depending on quick-xml >= 0.41.
"RUSTSEC-2026-0194", # quadratic duplicate-attribute check
"RUSTSEC-2026-0195", # unbounded namespace-declaration allocation
]

# Informational advisories (unmaintained / unsound / notice) are reported but
# do not fail the build; vulnerabilities do.
informational_warnings = ["unmaintained", "unsound", "notice"]
13 changes: 13 additions & 0 deletions .github/workflows/ghcr-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ jobs:
if: github.event_name != 'pull_request'
run: |
SHORT_SHA="${GITHUB_SHA::12}"
# Point podman's credential store at the DOCKER config path instead
# of its default ${XDG_RUNTIME_DIR}/containers/auth.json.
# REGISTRY_AUTH_FILE is honoured by both `podman login` and
# `podman push`, so one export covers the whole step.
#
# Why: the `attest-build-provenance` step below runs with
# `push-to-registry: true` and resolves registry credentials via the
# Docker config. With podman's default store it finds none and fails
# with "No credentials found for registry ghcr.io" — AFTER the image
# has already been pushed, which is why the image exists but the run
# is red.
mkdir -p "$HOME/.docker"
export REGISTRY_AUTH_FILE="$HOME/.docker/config.json"
echo "${{ secrets.GITHUB_TOKEN }}" \
| podman login ghcr.io -u "${{ github.actor }}" --password-stdin
# --digestfile records the real sha256 of the pushed manifest so the
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/governance.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
# SPDX-License-Identifier: MPL-2.0
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
name: Governance

on:
Expand All @@ -14,4 +14,4 @@ permissions:

jobs:
governance:
uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@d7c22711e830e1f383846472f6e9b99debdb201e
uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@45108f95e404e8e17896a56596d0db1cc7883c46
10 changes: 7 additions & 3 deletions .github/workflows/hypatia-scan.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
# SPDX-License-Identifier: MPL-2.0
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
name: Hypatia Security Scan

on:
Expand All @@ -13,8 +13,12 @@ on:

permissions:
contents: read
security-events: read
# Must be `write`, not `read`: hypatia-scan-reusable.yml declares
# `security-events: write` as of standards 45108f95e404, and GitHub refuses
# to start a reusable-workflow call whose caller grants less than the
# reusable declares (the failure mode is `startup_failure`, with no log).
security-events: write

jobs:
scan:
uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@d7c22711e830e1f383846472f6e9b99debdb201e
uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@45108f95e404e8e17896a56596d0db1cc7883c46
10 changes: 6 additions & 4 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: MPL-2.0
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
name: GitHub Pages (Ddraig SSG)
on:
push:
Expand All @@ -18,9 +20,9 @@ jobs:
image: ghcr.io/stefan-hoeck/idris2-pack@sha256:f0758996a931fb35d9ecb1de273c4d59dabe2a09b433afc7e357f65a08b7e1ff
steps:
- name: Checkout Site
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Checkout Ddraig SSG
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: hyperpolymath/ddraig-ssg
path: .ddraig-ssg
Expand All @@ -37,7 +39,7 @@ jobs:
fi
./.ddraig-ssg/build/exec/ddraig build src _site https://hyperpolymath.github.io/${GITHUB_REPOSITORY#*/}
- name: Upload artifact
uses: actions/upload-pages-artifact@v5
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: '_site'
deploy:
Expand All @@ -50,4 +52,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
4 changes: 2 additions & 2 deletions .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
# SPDX-License-Identifier: MPL-2.0
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
name: OSSF Scorecard

on:
Expand All @@ -14,7 +14,7 @@ permissions:

jobs:
scorecard:
uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@d7c22711e830e1f383846472f6e9b99debdb201e
uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@45108f95e404e8e17896a56596d0db1cc7883c46
permissions:
contents: read
security-events: write
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/secret-scanner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ concurrency:

permissions:
contents: read
# secret-scanner-reusable.yml's `gitleaks` job declares JOB-level
# `pull-requests: write` + `actions: read` (its own comment: "Reusable-
# workflow permission blocks OVERRIDE the caller's, so this MUST live here
# at source"). A caller granting less than the reusable declares is refused
# before any job starts — the observed failure was `startup_failure` with
# zero jobs and no log, which is the signature of caller-under-grant, NOT a
# scan result. gitleaks never ran at all.
pull-requests: write
actions: read

jobs:
scan:
Expand Down
44 changes: 22 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions audits/assail-classifications.a2ml
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,15 @@
(category "UnsafeDeserialization")
(audit "VeriSimSearch.res:80-200 — six try-wrapped stringify→parseExn round-trips")
(rationale "parse of self-stringified JSON inside try; cannot throw on external input"))

;; ── Allocation bounded by an explicit guard the scanner cannot see ──
;; assail flags the growth pattern (String::new + push_str in a loop)
;; syntactically; it does not prove bounds, so the guard added below does
;; not clear the finding. Re-verified 2026-07-21: still reported after the
;; fix, hence this entry rather than a code change alone.
(classification
(file "rust-core/verisim-repl/src/main.rs")
(category "UnboundedAllocation")
(audit "main.rs — REPL backslash-continuation buffer `query_buf`; guarded by MAX_QUERY_BUF_BYTES (1 MiB) since 2026-07-21")
(rationale "growth is bounded: the continuation branch checks query_buf.len() + line + 1 against MAX_QUERY_BUF_BYTES and clears the buffer on overflow, so the allocation cannot exceed 1 MiB regardless of input length"))
)
40 changes: 33 additions & 7 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,40 @@
[advisories]
db-path = "~/.cargo/advisory-db"
db-urls = ["https://github.com/rustsec/advisory-db"]
# Transitive deps in the `burn` ML stack we cannot fix downstream.
# Each entry is reviewed when bumping burn; remove once upstream migrates.
# Reviewed exceptions. Keep this list minimal, dated, and justified: every
# entry must name the blocking upstream and the condition for its removal.
#
# Removed 2026-07-21: the five burn-era entries (RUSTSEC-2024-0436 paste,
# RUSTSEC-2025-0134 rustls-pemfile, RUSTSEC-2025-0141 bincode,
# RUSTSEC-2026-0002 lru, RUSTSEC-2026-0105 core2). The `burn` ML stack is no
# longer a dependency at all (0 burn crates in Cargo.lock) and cargo-deny
# reported every one as `advisory-not-detected`. They suppressed nothing.
#
# WARNING when editing this file: `db-path` below is created empty on first
# run, and a cargo-deny invocation against an unpopulated advisory database
# reports "advisories ok" having checked NOTHING. Confirm the database is
# populated (it should contain crates/<name>/RUSTSEC-*.md) before trusting a
# green local result. CI clones a fresh database every run and is the
# authority; a local pass that CI contradicts means the local database, not CI,
# is wrong.
#
# Note also that cargo-deny's advisory detection is sensitive to how the
# dependency graph is resolved: `cargo deny check advisories` with default
# features does NOT surface the quick-xml advisories below, while
# `--all-features` and the CI container both do. The entries stay because the
# stricter resolution is the one that matters.
ignore = [
"RUSTSEC-2024-0436", # paste (unmaintained) — burn-wgpu → cubecl-cpu → tracel-llvm
"RUSTSEC-2025-0134", # rustls-pemfile (unmaintained) — axum-server
"RUSTSEC-2025-0141", # bincode (unmaintained) — burn-core
"RUSTSEC-2026-0002", # lru (unsound IterMut) — transitive
"RUSTSEC-2026-0105", # core2 (unmaintained + yanked) — rav1e → ravif → image → burn-dataset
# quick-xml 0.37.5 — two DoS advisories, both fixed upstream in 0.41.0.
# Reached ONLY through oxigraph -> {oxrdfxml, sparesults}. oxigraph 0.5.9 is
# the latest published release and still requires quick-xml ^0.37, so there
# is no resolution of this tree that avoids it.
# Exposure: verisim-graph's `oxigraph-backend` feature is NOT in `default`
# (rust-core/verisim-graph/Cargo.toml, `default = []`), so a stock build
# does not link quick-xml; only RDF/XML and SPARQL-XML parsing of untrusted
# input on an opt-in build is affected.
# REMOVE WHEN: oxigraph publishes a release requiring quick-xml >= 0.41.
"RUSTSEC-2026-0194", # quadratic duplicate-attribute check
"RUSTSEC-2026-0195", # unbounded namespace-declaration allocation
]

[licenses]
Expand Down
13 changes: 13 additions & 0 deletions elixir-orchestration/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ defmodule VeriSim.MixProject do
# GHSA-468c-vq7p-gh64 fix (multipart-header buffer exhaustion, High).
{:plug, "~> 1.19 and >= 1.19.2"},

# hpax is a transitive of bandit (and of mint) but pinned directly to
# enforce the GHSA-jj2p-32j7-whj2 fix — unbounded HPACK integer decoding
# allows an unauthenticated DoS (CVE-2026-58226, High).
{:hpax, "~> 1.0 and >= 1.0.4"},

# mint is a transitive of req -> finch but pinned directly to enforce four
# fixes landed across 1.9.1-1.9.3:
# GHSA-qrfr-wh4c-3qhw unbounded HTTP/1 header + trailer accumulation (High)
# GHSA-c59h-fq4p-r36r whole chunked body buffered in decode_body/5 (High)
# GHSA-8pf6-g464-h6h9 zero-length HTTP/2 CONTINUATION cap bypass (Medium)
# GHSA-x3x7-96vm-6h2w sign-tolerant chunk-size parser -> smuggling (Medium)
{:mint, "~> 1.9 and >= 1.9.3"},

# JSON encoding/decoding
{:jason, "~> 1.4"},

Expand Down
Loading
Loading