mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-26 11:49:16 +00:00
cursor/critical-bug-management-cc9d
8 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c67478b50d |
chore(security): VEX three new compose CVE findings and correct dependency comment (#1201)
Trivy reported three new advisories against the compose binary today: - CVE-2026-41568 (docker cp symlink-swap empty-file creation, sibling of CVE-2026-42306) - CVE-2026-33997 (Moby plugin install privilege bypass) - GHSA-pmwq-pjrm-6p5r (in-toto-golang glob-negation operator mismatch) All three are daemon-side or supply-chain attestation code paths that compose only embeds as client-side libraries. Sencho invokes compose exclusively for up/down/ps against user-authored compose files, never runs daemon endpoints, never performs plugin installation, and never verifies in-toto attestations. Each gets a not_affected statement with a full impact rationale; bump version 7 to 8 and last_updated to today. Also correct the compose-builder comment in Dockerfile. The previous text claimed compose v5.1.3 "eliminated CVE-2026-34040 and CVE-2026-33997 at the dependency level" by moving docker/docker to an indirect dep. That is wrong: the module is still pulled via buildkit and other transitive paths, the CVEs still appear in scans, and they are tracked in the VEX file rather than eliminated. The corrected comment points the reader at the VEX file as the source of truth for these findings. |
||
|
|
0951a0e792 |
chore(deps): bump containerd to v2.2.4 to clear CVE-2026-46680 (#1199)
The compose-builder stage now pulls containerd/v2 v2.2.4 alongside the existing otel security bumps. containerd v2.2.3 (the version pinned by docker/compose v5.1.3) carries CVE-2026-46680, a runAsNonRoot evasion in the runtime executor; v2.2.4 is the upstream patch release that fixes it. The vulnerable code path is daemon-side and was never reachable from compose, but bumping at the dependency level removes the entry from the SBOM rather than relying on a VEX suppression. Removed the corresponding statement from security/vex/sencho.openvex.json and bumped version + last_updated. The remaining three statements (docker/docker daemon CVEs) stay suppressed: the fix lives on a new github.com/moby/moby/v2 module path, and compose has not migrated imports yet, so no resolvable version bump clears them. |
||
|
|
b740dd1078 |
feat(resources): protect Sencho's own image, network, volumes from deletion (#1149)
* feat(resources): protect Sencho's own image, network, volumes from deletion Adds SelfIdentityService that reads HOSTNAME at startup and inspects the running Sencho container via Dockerode to record its image ID, attached networks, named volumes, and container ID. The classification API marks these with isSencho:true, destructive delete routes return 423 Locked when the target matches self, the orphan-containers API filters the Sencho container out so it cannot be selected and purged from the Unmanaged tab, and the managed-prune path adds an explicit self filter for defense-in-depth on top of Docker's in-use semantics. The Resources view renders a Sencho pill alongside the managed badge on matching rows and disables the trash control with a hover tooltip. When Sencho runs outside Docker (dev mode), inspect returns 404, the service stays empty, and every isOwn* returns false so today's behaviour is preserved. * fix(resources): handle sha256-prefixed image IDs and custom hostnames Addresses independent-review findings on PR #1149: - Strip sha256: prefix in POST /api/system/images/delete before validating the ID, matching the inspect route's handling. Without this, /system/images responses round-trip through the UI as sha256:<hex> and got 400 Invalid image ID format before rejectIfSelf could run. - Add /proc/self/cgroup fallback to SelfIdentityService so custom --hostname, Compose hostname:, or --uts=host setups still self-identify. HOSTNAME inspect runs first; on 404 the service parses the cgroup file for a 64-hex container ID (cgroupv1 docker, cgroupv2 docker, podman libpod formats all covered) and retries inspect with that ID. - Restrict prefix matching in isOwnNetwork / matchesId to hex-shaped candidates (12 to 64 hex chars), so a non-Sencho network whose name happens to start with a hex prefix of Sencho's network ID is no longer flagged as self. - Trim the resources.mdx Note to customer-visible behaviour without enumerating every tab. - New tests: prefixed-image-ID 200 path, three cgroup file format parses (v1, v2, podman) plus the no-match and missing-file cases, HOSTNAME-404-then-cgroup-success fallback path, name-collision regression for the hex-only prefix rule, and an empty-cache no-regression check. Test hygiene: mockReset on the inspect stub and restoreAllMocks in afterEach so spies do not leak across tests. * chore(security): VEX not_affected for CVE-2026-46680 (containerd in docker-compose) Trivy now flags CVE-2026-46680 HIGH on usr/local/lib/docker/cli-plugins/docker-compose, which statically embeds github.com/containerd/containerd/v2 v2.2.3 (compose v5.1.3's resolved module graph). The CVE is a runtime-executor flaw: containerd's runc invocation can be tricked into running a Kubernetes pod marked runAsNonRoot as root via crafted user ID handling. The vulnerable code path is reached only by containerd-shim executing a container with a populated OCI runtime spec on the daemon side. docker-compose vendors the containerd Go module purely as a client (gRPC stubs, API types, shared utilities); it never executes containers and never enforces runAsNonRoot. Sencho's compose usage (up / down / ps against user-authored files) cannot construct a Kubernetes pod security context. The vulnerable path is unreachable. Adds a not_affected entry to security/vex/sencho.openvex.json with justification vulnerable_code_not_in_execute_path, bumps version 5 to 6, and updates last_updated to 2026-05-22 per Directive 23. |
||
|
|
596cce3507 |
fix(security): suppress CVE-2026-41567 and CVE-2026-42306 against vendored docker-compose moby library (VEX) (#1102)
The v0.81.13 Docker publish workflow failed on the post-build Trivy
re-scan because the moby/Docker vulnerability database picked up two new
HIGH CVEs against `github.com/docker/docker v28.5.2+incompatible`, which
docker-compose v5.1.3 vendors statically as a client-side API/codec
library. The CVEs were not present in the PR-side Trivy DB three hours
earlier, so PR CI passed but the release re-scan failed.
Both CVEs are daemon-side: CVE-2026-41567 targets the daemon's
PUT /containers/{id}/archive handler, CVE-2026-42306 is a race in the
daemon-side bind-mount resolution that backs `docker cp`. docker-compose
never acts as the daemon, never serves these routes, and Sencho only
invokes compose for up/down/ps. The vulnerable code paths are
unreachable. The fix lives on the github.com/moby/moby/v2 module path;
until upstream compose migrates, v28.5.2+incompatible remains the only
Go-module-resolvable version compose can reference. Same triage shape as
the existing CVE-2026-34040 entry, so the new statements mirror its top-
level products purl form.
Bumps OpenVEX document version 4 -> 5 and updates last_updated /
timestamp to 2026-05-18.
|
||
|
|
3da0aa6036 |
chore: migrate repository URLs from AnsoCode/Sencho to studio-saelix/sencho
Updates all hardcoded GitHub repository references across 21 files: - package.json: repository URL, bugs URL, homepage, description, author - CONTRIBUTING.md: bug report template URL - SECURITY.md: advisory URL, cosign cert-identity regexp - .github/CODEOWNERS: @AnsoCode -> @studio-saelix/maintainers - .github/workflows/ci.yml: repositories scope (Sencho -> sencho), docs-sync git URL - .github/workflows/cla.yml: path-to-document URL - .github/workflows/docker-publish.yml: cosign verify comment - frontend/**/*.tsx: issues and changelog links (3 components) - frontend/public/.well-known/security.txt: Contact and Policy URLs - security/vex/sencho.openvex.json: @id field - docs/openapi.yaml: license URL - docs/docs.json: navbar and footer GitHub links (5 instances) - docs/security.mdx: advisory and SECURITY.md links - docs/reference/verifying-images.mdx: repo link + cosign regexp + legacy identity note - docs/reference/contact.mdx: issues, LICENSE, advisory, policy, CoC links - docs/reference/security-advisories.mdx: releases link - docs/operations/verifying-images.mdx: cosign regexps and VEX download URL (6 instances) - docs/operations/upgrade.mdx: releases links (2 instances) - backend/src/utils/version-check.ts: GitHub Releases API endpoint CHANGELOG.md intentionally excluded (release-please managed). Legacy cosign identity note added for pre-migration image verification. |
||
|
|
e124874dac |
fix(docker): upgrade CLI to v29.4.1 and Compose to v5.1.3, clear VEX (#836)
* fix(docker): upgrade CLI to v29.4.1 and Compose to v5.1.3, clear VEX * fix(vex): restore CVE-2026-34040 not_affected statement for compose * fix: correct VEX product matching for CVE-2026-34040 |
||
|
|
06d9ef5904 |
fix(docker): build compose plugin from ./cmd, not ./cmd/compose (#803)
* fix(docker): build compose plugin from ./cmd, not ./cmd/compose The compose-builder stage in Dockerfile was building ./cmd/compose, which in docker/compose v5.1.2 is `package compose` (cobra command definitions), not the CLI plugin entry point. `go build -o file pkg` against a non-main package writes a Go archive; COPY and chmod accept it, but the kernel cannot exec an ar-format file, so the Docker CLI plugin manager rejected the binary and surfaced only as `docker: unknown command: docker compose` in the v0.64.0 release smoke gate. The plugin's actual main package is at ./cmd (cmd/main.go calls plugin.Run from the cli-plugins framework), per the upstream Makefile in v5.1.2. Also fix the version ldflag to target the v5 module path: in v5 the module moved from github.com/docker/compose/v2 to .../v5, so the previous -X .../v2/internal.Version= silently no-op'd and `docker compose version` would have reported an empty string even after the build target fix. Add -trimpath and -s -w to match the upstream Makefile's release flags. Add an inline ELF-magic sanity check inside the compose-builder stage so this exact failure mode (non-main package emitting an archive) fails the build at the producer instead of surfacing 200 lines later. Hex match via `od -tx1` works on both busybox and GNU coreutils; the named-character form (`od -c`) renders fields differently across the two. Add a binary smoke step to the docker-validate PR job that mirrors the release-time gate, so a regression in either the CLI or compose source build is caught at PR review time rather than at tag-push time. * fix(vex): match Trivy purl format for bundled docker/docker version The compose plugin build target fix exposes a real consequence: now that compose-builder produces a true ELF binary (rather than a Go archive), Trivy can read the embedded Go module metadata and correctly reports the bundled docker/docker dependency as `v28.5.2+incompatible`. The existing VEX subcomponent ID omitted the `+incompatible` Go-module suffix, so Trivy's purl matcher rejected the suppression and CVE-2026-34040 surfaced in the docker-validate scan against the rebuilt image. Update the @id to the literal version Trivy emits and bump the document version per OpenVEX spec. The justification (compose acts as a CLI client, never as a daemon, so the authz-hook path is unreachable) is unchanged and continues to apply to v28.5.2+incompatible identically. * docs(security): explain why CVE-2026-34040 cannot be upgraded out A direct in-build upgrade attempt (`go get github.com/docker/docker@<sha of docker-v29.3.1>`) fails with: invalid version: go.mod has post-v1 module path "github.com/moby/moby/v2" at revision f78c987a moby/moby migrated its Go module path to `github.com/moby/moby/v2` on the docker-29.x branch. The legacy `github.com/docker/docker` import path is therefore frozen at v28.5.2+incompatible from Go's perspective; the proxy.golang.org listing for that module path confirms no v29.x version is resolvable. compose v5.1.2 (and v5.1.3, the latest tag at the time of writing) both still import the legacy path, so the bundled docker/docker library cannot be moved past v28.5.2+incompatible until upstream compose migrates its imports. Document the constraint in two places so a future maintainer (or future me) does not re-attempt the same `go get` and arrive at the same dead end: - Dockerfile compose-builder stage: comment block above the build step. - security/vex/sencho.openvex.json: expand the CVE-2026-34040 statement's impact_statement to spell out the upstream module-split blocker. The not_affected status (compose runs as a CLI client, never executes the daemon authz hook code path) is the principled triage and remains the correct OpenVEX call, not a deferred upgrade. No build or runtime behaviour changes. Pure documentation enrichment. * fix(security): mirror CVE-2026-34040 VEX statement in .trivyignore Trivy reports `Some vulnerabilities have been ignored/suppressed` but still fails the docker-validate scan on CVE-2026-34040, because the OpenVEX statement's product identifier `pkg:oci/sencho` cannot match the build-local image tag `sencho:pr-test`. Trivy does not generate an OCI purl for images that lack a registry digest (aquasecurity/trivy issue 9399), so VEX product matching is a no-op at PR and release scan time. The dual-layer pattern documented in .trivyignore's header was designed for exactly this case: VEX is the canonical, attested, published triage record, and .trivyignore mirrors entries that scan-time matching cannot resolve, with a comment pointing to the corresponding VEX justification. The CVE-2026-34040 OpenVEX statement is unchanged (status=not_affected, justification=vulnerable_code_not_in_execute_path). The .trivyignore entry is a build-time scan filter only, with a referencing comment so auditors land on the VEX file as the source of truth. CVE-2026-39883 already follows this pattern and continues to. |
||
|
|
3668c71860 |
feat(security): add SBOM attestations, VEX document, and retire .trivyignore (#790)
* feat(security): add SBOM attestations, VEX document, and retire .trivyignore Add OpenVEX triage document (security/vex/sencho.openvex.json) for the 5 residual CVEs vendored inside docker/compose v5.1.2 that were carried over from the previous PR. All 5 are marked not_affected with justifications. Configure Trivy in both CI and release workflows to consume the VEX document via trivy.yaml so the same source of truth gates PR scans and release scans. Delete .trivyignore, which is fully superseded by the VEX file. Add two new release pipeline steps after image publication: - CycloneDX 1.6 SBOM via anchore/sbom-action (also installs syft) - SPDX 2.3 SBOM via syft directly (reuses OCI layer cache from prior step) Both are attached as cosign OCI referrer attestations (keyless, OIDC-signed) and uploaded as GitHub Release assets alongside the OpenVEX file. Bump docker-publish.yml permissions from contents:read to contents:write, required for softprops/action-gh-release to create Release assets. Add docs/operations/verifying-images.mdx with copy-paste verification commands for all supply-chain artifacts: signature, SLSA provenance, CycloneDX SBOM, SPDX SBOM, OpenVEX, and Rekor entry. Update docs.json navigation and expand the Supply chain security section in docs/security.mdx. Add a Verifying Release Artifacts section to SECURITY.md. * fix(vex): cover otel SDK CVE-2026-39883 in rebuilt Docker CLI binary The rebuilt Docker CLI v29.4.0 vendors otel/sdk v1.42.0, which still contains CVE-2026-39883 (BSD kenv PATH hijacking; fixed in v1.43.0). docker-compose v5.1.2 vendors otel/sdk v1.38.0 separately. The original VEX statement only covered the compose binary's location and version, so Trivy's scan of /usr/local/bin/docker was not suppressed. Add a second subcomponent entry for the CLI binary path with the correct vendored version. The not_affected justification (BSD-only code path; we ship linux/amd64 and linux/arm64 only) holds for both binaries. * fix(ci): use list form for vulnerability.vex in trivy.yaml Trivy's config schema requires vulnerability.vex to be a list (mapped to the multi-value --vex flag). The previous bare-string value was silently dropped, so the OpenVEX document was never loaded and HIGH findings already covered by VEX statements still failed the scan. * fix(ci): mirror VEX CVE in .trivyignore for local-image scan Trivy does not emit an OCI purl for locally-built images without a RepoDigests entry (aquasecurity/trivy#9399), so OpenVEX product matching against the CI build target sencho:pr-test resolves to no artifact and every statement is silently dropped. The VEX document remains the canonical triage record and is still attached as a cosign attestation on the published image; this file just mirrors the single CVE that surfaces on the local scan so CI does not block on a finding already triaged in VEX. Updates the Trivy step comment to document the relationship between the two files. |