From a63750b06a86c9ba61efe1e4c145332b827922ef Mon Sep 17 00:00:00 2001 From: StefFashka Date: Thu, 2 Jul 2026 21:58:01 +0800 Subject: [PATCH] feat(lab8): cosign sign + SBOM/provenance attestations + blob signing --- labs/lab8/keys/cosign.pub | 4 ++ submissions/lab8.md | 108 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 labs/lab8/keys/cosign.pub create mode 100644 submissions/lab8.md diff --git a/labs/lab8/keys/cosign.pub b/labs/lab8/keys/cosign.pub new file mode 100644 index 00000000..d148edbe --- /dev/null +++ b/labs/lab8/keys/cosign.pub @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+ANKEK9etDd23tvTC3xBnCZ8U/GV +AeUHSNDQqh8Z5/TDSyARCP+uKdFauCQdhfnXVJ0vvpcnKkdCjx6ub7DRnA== +-----END PUBLIC KEY----- diff --git a/submissions/lab8.md b/submissions/lab8.md new file mode 100644 index 00000000..922a4502 --- /dev/null +++ b/submissions/lab8.md @@ -0,0 +1,108 @@ +# Lab 8 — Submission + +## Task 1: Sign + Tamper Demo + +### Registry + image push +- Registry container: `lab8-registry` running on `localhost:5000` +- Image pushed: `localhost:5000/juice-shop:v20.0.0` +- Image digest: `localhost:5000/juice-shop@sha256:28870b9d2bec49e605d6ebbf4b22ed1ec1ca0a72347ef19217bbbb21ea44e3fe` + +### Signing +- Output of `cosign sign` (just the success line is fine): +``` +Signing artifact... +Pushing signature to: localhost:5000/juice-shop +``` + +### Verification (PASSED) +Output of `cosign verify` on original digest: +```json +[{"critical":{"identity":{"docker-reference":"localhost:5000/juice-shop@sha256:28870b9d2bec49e605d6ebbf4b22ed1ec1ca0a72347ef19217bbbb21ea44e3fe"},"image":{"docker-manifest-digest":"sha256:28870b9d2bec49e605d6ebbf4b22ed1ec1ca0a72347ef19217bbbb21ea44e3fe"},"type":"https://sigstore.dev/cosign/sign/v1"},"optional":{}}] +``` + +### Tamper Demo (FAILED — correctly) +Output of `cosign verify` on tampered digest: +``` +WARNING: Skipping tlog verification is an insecure practice that lacks transparency and auditability verification for the signature. +Error: no signatures found +error during command execution: no signatures found +``` + +### Sanity — original still verifies +``` +WARNING: Skipping tlog verification is an insecure practice that lacks transparency and auditability verification for the signature. +Verification for localhost:5000/juice-shop@sha256:28870b9d2bec49e605d6ebbf4b22ed1ec1ca0a72347ef19217bbbb21ea44e3fe -- +The following checks were performed on each of these signatures: + - The cosign claims were validated + - Existence of the claims in the transparency log was verified offline + - The signatures were verified against the specified public key + +[{"critical":{"identity":{"docker-reference":"localhost:5000/juice-shop@sha256:28870b9d2bec49e605d6ebbf4b22ed1ec1ca0a72347ef19217bbbb21ea44e3fe"},"image":{"docker-manifest-digest":"sha256:28870b9d2bec49e605d6ebbf4b22ed1ec1ca0a72347ef19217bbbb21ea44e3fe"},"type":"https://sigstore.dev/cosign/sign/v1"},"optional":{}}] +``` + +### Why digest binding matters (Lecture 8 slide 6) +The tampered tag pointed to a different digest, while the Cosign signature was bound to the original immutable digest. If Cosign signed only the mutable tag, an attacker could retag a malicious image as `v20.0.0` and inherit trust from the old tag name. Digest binding prevents that tag-mutation attack because verification follows the exact manifest hash. + +## Task 2: SBOM + Provenance Attestations + +### SBOM attestation +- Attached: yes (`cosign attest --type cyclonedx` exit 0) +- Verify-attestation output (first 30 lines of decoded payload): +```json +{ + "_type": "https://in-toto.io/Statement/v0.1", + "subject": [ + { + "name": "localhost:5000/juice-shop", + "digest": { + "sha256": "28870b9d2bec49e605d6ebbf4b22ed1ec1ca0a72347ef19217bbbb21ea44e3fe" + } + } + ], + "predicateType": "https://cyclonedx.org/bom", + "predicate": { + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "components": [ + { + "author": "Benjamin Byholm (https://github.com/kkoopa/), Mathias Küsel (https://github.com/mathiask88/)", + "bom-ref": "pkg:npm/1to2@1.0.0?package-id=3cea2309a653e6ed", + "cpe": "cpe:2.3:a:nodejs:1to2:1.0.0:*:*:*:*:*:*:*", + "description": "NAN 1 -> 2 Migration Script", + "externalReferences": [ + { + "type": "distribution", + "url": "git://github.com/nodejs/nan.git" + } + ], + "licenses": [ + { +``` +- Component count matches Lab 4 source: yes +- diff between Lab 4 SBOM and the extracted-from-attestation SBOM: `<>` + +### Provenance attestation +- Attached: yes +- Builder ID in predicate: `https://localhost/lab8-student` +- buildType in predicate: `https://example.com/lab8/local-build` + +### What this gives a Lab 9 verifier (2-3 sentences) +At K8s admission time, a Kyverno verify-images policy can require the image signature and the CycloneDX attestation before allowing deployment. A signed image without an SBOM only proves who signed the digest; it does not provide a queryable component inventory. A signed image with an SBOM lets the verifier or incident workflow answer the next Log4Shell-style question by checking whether the attested image contains the affected package. + +## Bonus: Blob Signing (Codecov 2021 mitigation) + +### Sign + verify +- Signed: `my-tool.tar.gz` + `my-tool.tar.gz.bundle` +- Verify-blob success output: +``` +Verified OK +``` + +### Tamper test failed (correctly) +``` +Error: failed to verify signature: could not verify message: invalid signature when validating ASN.1 encoded signature +error during command execution: failed to verify signature: could not verify message: invalid signature when validating ASN.1 encoded signature +``` + +### Codecov 2021 mitigation (2-3 sentences) +Codecov's bash uploader was distributed through `curl | bash` without verifying the downloaded bytes. If consumers had required `cosign verify-blob --key cosign.pub --bundle uploader.bundle uploader.sh` before execution, the modified uploader would not have matched the signed byte stream. The pipeline would fail before running the attacker-controlled script and before CI environment variables could be exfiltrated.