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
8 changes: 3 additions & 5 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@ name: codeql
#
# Findings surface in the repo Security > Code scanning tab (SARIF upload), so on
# top of push/PR we run a weekly scheduled sweep to re-scan main against any
# newly-shipped CodeQL queries even when the code is quiet.
#
# NB: SARIF upload requires GitHub code scanning enabled on the repo (GitHub
# Advanced Security on a private repo). Until that's on, the analyze step's
# upload will fail.
# newly-shipped CodeQL queries even when the code is quiet. This repo is public,
# so code scanning is free + available with no setup — the analyze step's SARIF
# upload just works. (On a private repo it would need GitHub Advanced Security.)

on:
push:
Expand Down
4 changes: 2 additions & 2 deletions docs/plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -1075,11 +1075,11 @@ What changed, why, where to look for details.
Built the heart of the self-contained channel. **`packaging/packetnet-selfupdate`** is the helper the self-contained install ships as `/usr/lib/packetnet/packetnet-update` (the same `packetnet-update.service` unit as apt, different body): fetch `latest.json` from the configured feed → pick this arch's tarball → download → **sha256-verify** (checksum-only; a marked seam for cosign later) → unpack into `releases/<new>` via a temp dir + atomic rename → **flip the `current` symlink** (the unit's ExecStart target) → restart → poll `/healthz` → on failure **flip back to `$prev` and restart** → GC keeping exactly `current`+`$prev`. Parses the manifest without a jq dependency; paths/restart/health are `PDN_*`-overridable so it's testable without systemd. A fixture smoke (`scripts/selfupdate-smoke.sh`, wired into `deb-smoke`) proves happy-path/checksum-mismatch-refused/rollback — and caught a real bug mid-build: GC by mtime deleted the **rollback target** (it's `$prev`, not necessarily the 2nd-newest), fixed to protect `current`+`$prev` explicitly. **API generalized:** `ISystemUpdateLauncher.StartAptUpdateAsync` → `StartUpdateAsync` (channel-agnostic — starts the one oneshot whatever the install's helper does), and `POST /api/v1/system/update` now launches for **both** apt and self-contained with a channel-aware `via`/audit; only `unknown` → 409 (self-contained stopped returning 501). `SystemUpdateApiTests` updated; full Node suite green. **Remaining (slice 2c):** `installers/install.sh` (lay out `releases`/`current` + the self-contained unit + marker + the helper + polkit + `/etc/packetnet/update.conf` + user/dirs + bootstrap), the feed URL in node config, and the available-version check feeding the UI.
### 2026-06-13 — CodeQL reworked to buildless (C# + web TS), dropping the traced Release build

Refined the `codeql.yml` from the entry below before it ever ran. Switched both languages to **`build-mode: none`** (buildless extraction) and matrixed two SHIPPED codebases — `csharp` (the .NET product) and `javascript-typescript` (`web/packetnet-ui`, the served SPA). Buildless C# skips the full Release compile entirely, so the workflow no longer needs the exclusive `flock -x /tmp/pdn-ci-heavy.lock` (it isn't the CPU-heavy compile that lock guards) — much lighter on the contended self-hosted box, at a small completeness cost vs a traced build. Kept `[self-hosted, Linux, X64]`; added `packages: read` (private query packs); bumped the action to `@v4`. The python/rust/c spec dirs stay out of scope (reference artifacts, not product). GitHub's own "Advanced setup" template was declined — it targets `ubuntu-latest`/`macos-latest` (violates the no-hosted-runners rule) and would have clobbered this file. The GHAS/code-scanning-enabled caveat below still applies.
Refined the `codeql.yml` from the entry below before it ever ran. Switched both languages to **`build-mode: none`** (buildless extraction) and matrixed two SHIPPED codebases — `csharp` (the .NET product) and `javascript-typescript` (`web/packetnet-ui`, the served SPA). Buildless C# skips the full Release compile entirely, so the workflow no longer needs the exclusive `flock -x /tmp/pdn-ci-heavy.lock` (it isn't the CPU-heavy compile that lock guards) — much lighter on the contended self-hosted box, at a small completeness cost vs a traced build. Kept `[self-hosted, Linux, X64]`; added `packages: read` (private query packs); bumped the action to `@v4`. The python/rust/c spec dirs stay out of scope (reference artifacts, not product). GitHub's own "Advanced setup" template was declined — it targets `ubuntu-latest`/`macos-latest` (violates the no-hosted-runners rule) and would have clobbered this file. **Correction to the caveat in the entry below:** the repo is *public* (confirmed via the API — `visibility: public`), so code scanning is free + available with no setup; the SARIF upload just works and there is no GHAS/enable-it step (that caveat only applies to private repos).

### 2026-06-13 — CodeQL static analysis (C#) added; WebAuthn ceremony review (no findings)

Two follow-on security tracks after the #405 hardening pass. **(1) CodeQL** — new `.github/workflows/codeql.yml` runs the C# CodeQL analysis on `[self-hosted, Linux, X64]` (zero hosted-runner minutes, per the project rule) on push/PR to main + a weekly cron + dispatch; `build-mode: manual` (CPM + the `.slnx` solution defeat autobuild) with the Release build wrapped in the exclusive `flock -x /tmp/pdn-ci-heavy.lock` like `fuzz.yml`. NB: SARIF upload to the Security tab needs GitHub code scanning enabled on the repo (GHAS on a private repo) — flagged for the owner; the workflow itself is correct regardless. **(2) WebAuthn / passkey ceremony review** — read the registration + assertion path (`PdnWebAuthnApi`, `WebAuthnFido2Builder`, `WebAuthnChallengeCache`, the credential store) end to end: **no exploitable findings.** Challenge is single-use (atomic `TryRemove`) + TTL'd off the injected clock + user-bound; RP-id/origins are pinned from config (a spoofed Host can't widen them); sign-count clone-detection is checked and persisted; credential↔user binding is enforced with a constant-time compare and global credential-id uniqueness; everything fails closed behind a single generic 401. Four non-defect observations recorded (UV=`Preferred` vs `Required` is a policy knob; the username-scoped `assert/begin` is an inherent passkey-existence oracle in the non-discoverable flow; an unused store method; clone-vs-generic log classification keys off an exception substring). Full write-up in [`docs/webauthn-review-2026-06-13.md`](webauthn-review-2026-06-13.md); the session's earlier tracks are in [`docs/security-review-2026-06-13.md`](security-review-2026-06-13.md).
Two follow-on security tracks after the #405 hardening pass. **(1) CodeQL** — new `.github/workflows/codeql.yml` runs the C# CodeQL analysis on `[self-hosted, Linux, X64]` (zero hosted-runner minutes, per the project rule) on push/PR to main + a weekly cron + dispatch; `build-mode: manual` (CPM + the `.slnx` solution defeat autobuild) with the Release build wrapped in the exclusive `flock -x /tmp/pdn-ci-heavy.lock` like `fuzz.yml`. (Reworked to buildless in the entry above; this manual-build form never ran.) SARIF upload surfaces in the Security > Code scanning tab — the repo is public, so that's free + available with no setup (no GHAS step; that caveat is private-repo-only). **(2) WebAuthn / passkey ceremony review** — read the registration + assertion path (`PdnWebAuthnApi`, `WebAuthnFido2Builder`, `WebAuthnChallengeCache`, the credential store) end to end: **no exploitable findings.** Challenge is single-use (atomic `TryRemove`) + TTL'd off the injected clock + user-bound; RP-id/origins are pinned from config (a spoofed Host can't widen them); sign-count clone-detection is checked and persisted; credential↔user binding is enforced with a constant-time compare and global credential-id uniqueness; everything fails closed behind a single generic 401. Four non-defect observations recorded (UV=`Preferred` vs `Required` is a policy knob; the username-scoped `assert/begin` is an inherent passkey-existence oracle in the non-discoverable flow; an unused store method; clone-vs-generic log classification keys off an exception substring). Full write-up in [`docs/webauthn-review-2026-06-13.md`](webauthn-review-2026-06-13.md); the session's earlier tracks are in [`docs/security-review-2026-06-13.md`](security-review-2026-06-13.md).

### 2026-06-13 — Web auth core security review (no findings) — written up

Expand Down
Loading