Chapter 34 Exercises: Supply Chain Security

Exercise 34.1: Dependency Inventory and Analysis

Difficulty: Beginner Objective: Create a comprehensive dependency inventory for a sample project and assess risk.

  1. Clone a sample open-source project (e.g., a Node.js Express application or a Python Flask application) from GitHub.
  2. Identify all direct dependencies listed in the project's manifest file (package.json, requirements.txt, or equivalent).
  3. Generate a complete dependency tree including all transitive dependencies. For npm, use npm ls --all. For pip, use pipdeptree.
  4. Count the total number of direct and transitive dependencies.
  5. For each direct dependency, record: package name, version, license, last update date, and number of weekly downloads.
  6. Identify any dependencies that have not been updated in the last 12 months.
  7. Write a one-paragraph risk assessment summarizing your findings.

Deliverable: A spreadsheet or markdown table of all direct dependencies with their metadata, plus your risk assessment paragraph.

Exercise 34.2: Vulnerability Scanning with Trivy

Difficulty: Beginner Objective: Use Trivy to scan a project for known vulnerabilities in dependencies.

  1. Install Trivy on your lab system.
  2. Scan a sample project directory: trivy fs --scanners vuln ./project-directory
  3. Scan a public Docker image: trivy image python:3.9-slim
  4. For each vulnerability found, record: CVE ID, severity, affected package, fixed version (if available).
  5. Categorize vulnerabilities by severity (Critical, High, Medium, Low).
  6. Research the top three most severe vulnerabilities. What is the attack vector? Is there a known exploit?
  7. Create a prioritized remediation plan.

Deliverable: Vulnerability scan report with categorized findings and remediation plan.

Exercise 34.3: SBOM Generation and Analysis

Difficulty: Intermediate Objective: Generate and analyze Software Bills of Materials using multiple tools.

  1. Choose a sample project with at least 20 dependencies.
  2. Generate an SBOM in CycloneDX format using Syft: syft packages dir:./project -o cyclonedx-json > sbom-cdx.json
  3. Generate an SBOM in SPDX format: syft packages dir:./project -o spdx-json > sbom-spdx.json
  4. Compare the two formats. What information does each contain? What are the differences?
  5. Use Grype to scan your CycloneDX SBOM for vulnerabilities: grype sbom:./sbom-cdx.json
  6. Upload your SBOM to OWASP Dependency-Track (install locally or use the demo instance). Explore the dashboard.
  7. Set up a CI/CD pipeline (GitHub Actions or local Jenkins) that automatically generates an SBOM on every build.

Deliverable: Both SBOM files, Grype scan results, screenshots of Dependency-Track dashboard, and CI/CD pipeline configuration.

Exercise 34.4: Dependency Confusion Simulation

Difficulty: Intermediate Objective: Understand dependency confusion by simulating the attack in a controlled environment.

  1. Set up a local npm registry using Verdaccio: npm install -g verdaccio && verdaccio
  2. Create a private package named @mycompany/internal-utils and publish it to your local registry.
  3. Create a project that depends on @mycompany/internal-utils and configure it to use your local registry.
  4. Now create a package named internal-utils (without the scope) version 99.0.0 and publish it to your local registry under a different feed URL to simulate a public registry.
  5. Misconfigure the project's .npmrc to simulate a vulnerable configuration where both registries are checked.
  6. Run npm install and observe which package is installed.
  7. Fix the configuration to prevent dependency confusion. Verify the fix works.
  8. Document the vulnerable vs. secure configurations.

Deliverable: Documentation showing the vulnerable configuration, the attack result, the fixed configuration, and verification.

Exercise 34.5: CI/CD Pipeline Security Audit

Difficulty: Intermediate Objective: Audit a GitHub Actions workflow configuration for security issues.

Review the following GitHub Actions workflow and identify all security issues:

name: Build and Deploy
on:
  pull_request_target:
    types: [opened, synchronize]

jobs:
  build:
    runs-on: ubuntu-latest
    permissions: write-all
    steps:
      - uses: actions/checkout@v3
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - run: echo "Building PR from ${{ github.event.pull_request.head.label }}"
      - run: echo "PR Title: ${{ github.event.pull_request.title }}"
      - uses: docker/build-push-action@v4
        with:
          push: true
          tags: ghcr.io/myorg/myapp:${{ github.event.pull_request.head.sha }}
      - name: Deploy to staging
        run: |
          curl -H "Authorization: Bearer ${{ secrets.DEPLOY_TOKEN }}" \
            https://deploy.myorg.com/stage
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET }}
  1. List every security issue you can find (aim for at least 6).
  2. For each issue, explain the risk and how an attacker could exploit it.
  3. Rewrite the workflow with all issues fixed.
  4. Add additional security controls that you would recommend.

Deliverable: Annotated audit of the original workflow, rewritten secure workflow, and list of additional recommended controls.

Exercise 34.6: Code Signing with Cosign

Difficulty: Intermediate Objective: Practice signing and verifying container images with Sigstore/Cosign.

  1. Install Cosign on your lab system.
  2. Build a simple Docker image from a Dockerfile.
  3. Push the image to a local or free container registry (e.g., Docker Hub, GitHub Container Registry).
  4. Sign the image using Cosign keyless signing: cosign sign <image-reference>
  5. Verify the signature: cosign verify <image-reference> --certificate-identity=<your-email> --certificate-oidc-issuer=<issuer>
  6. Generate a key pair and sign with an explicit key: cosign generate-key-pair then cosign sign --key cosign.key <image-reference>
  7. Verify with the public key: cosign verify --key cosign.pub <image-reference>
  8. Examine the Rekor transparency log entry for your signature.
  9. Configure a Kubernetes admission controller (e.g., Kyverno or Connaisseur) to reject unsigned images.

Deliverable: Documentation of each step with screenshots, the Rekor log entry, and Kubernetes admission controller configuration.

Exercise 34.7: OpenSSF Scorecard Assessment

Difficulty: Intermediate Objective: Evaluate open-source project security using OpenSSF Scorecard.

  1. Install the OpenSSF Scorecard CLI.
  2. Run Scorecard against three popular open-source projects of your choice (e.g., one well-maintained, one moderately maintained, one poorly maintained).
  3. For each project, record the overall score and individual check scores.
  4. Compare the results across the three projects.
  5. For the lowest-scoring project, identify the three most impactful improvements the maintainers could make.
  6. Research the Criticality Score for these same projects (if available).
  7. Write a recommendation memo (as if to your organization's engineering leadership) about dependency selection criteria based on your analysis.

Deliverable: Scorecard results for three projects, comparative analysis, and recommendation memo.

Exercise 34.8: Typosquatting Detection

Difficulty: Intermediate Objective: Build a tool to detect potential typosquatting packages.

  1. Write a Python script that takes a package name as input and generates potential typosquatting variations: - Character omission (e.g., reqests for requests) - Character substitution (e.g., requasts for requests) - Character transposition (e.g., reuqests for requests) - Hyphen/underscore confusion (e.g., request_s for requests) - Homoglyph substitution (e.g., using similar-looking Unicode characters)
  2. For each variation, check whether a package with that name exists on PyPI (use the PyPI JSON API).
  3. For any existing typosquat candidates, compare their metadata with the legitimate package (author, description, creation date, download count).
  4. Test your tool against five popular Python packages.
  5. Document any actual typosquatting attempts you discover.

Deliverable: Python script, test results for five packages, and documentation of any discovered typosquatting attempts.

Exercise 34.9: SLSA Provenance Verification

Difficulty: Advanced Objective: Implement and verify SLSA provenance for a build pipeline.

  1. Create a simple Go or Node.js application.
  2. Set up a GitHub Actions workflow that builds the application.
  3. Add the slsa-framework/slsa-github-generator to your workflow to generate SLSA provenance.
  4. Build the application and verify that provenance is generated.
  5. Download the provenance attestation and examine its contents.
  6. Verify the provenance using slsa-verifier: slsa-verifier verify-artifact <artifact> --provenance-path <provenance> --source-uri github.com/<org>/<repo>
  7. Modify the build to tamper with the artifact after building (add a byte to the binary). Attempt verification and confirm it fails.
  8. Document the difference between SLSA Level 1, 2, and 3 and which level your pipeline achieves.

Deliverable: GitHub repository with SLSA-enabled workflow, provenance attestation, verification results (both pass and fail), and SLSA level documentation.

Exercise 34.10: Supply Chain Threat Modeling

Difficulty: Advanced Objective: Conduct a comprehensive supply chain threat model for a sample application.

Using the MedSecure patient portal as your target:

  1. Draw a supply chain diagram showing all components: source code, dependencies, build system, distribution, runtime.
  2. Identify all trust boundaries in the supply chain.
  3. For each trust boundary, list potential attack vectors.
  4. Apply STRIDE (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege) to each component.
  5. Rank each threat by likelihood and impact.
  6. Map threats to relevant mitigations from SLSA, SBOM, and other frameworks discussed in this chapter.
  7. Identify the top 5 highest-risk threats and develop detailed mitigation plans for each.

Deliverable: Supply chain diagram, STRIDE analysis table, risk ranking, and detailed mitigation plans.

Exercise 34.11: Build System Security Hardening

Difficulty: Advanced Objective: Harden a CI/CD pipeline against supply chain attacks.

  1. Create a GitHub repository with a multi-stage CI/CD pipeline (build, test, scan, deploy).
  2. Implement the following hardening measures: - Pin all GitHub Actions to specific commit SHAs - Set minimum required permissions for each job - Add SBOM generation step - Add vulnerability scanning step with Trivy or Grype - Add container image signing with Cosign - Configure branch protection and CODEOWNERS for pipeline files - Implement hash verification for downloaded tools
  3. Verify each hardening measure is working correctly.
  4. Create a security scoring rubric and score your pipeline.
  5. Document any hardening measures you could not implement and explain why.

Deliverable: GitHub repository with hardened pipeline, security scoring rubric, and documentation.

Exercise 34.12: Incident Response Tabletop: Supply Chain Compromise

Difficulty: Advanced Objective: Practice incident response for a supply chain attack scenario.

Scenario: Your organization's security monitoring has detected that a popular Python package your backend services depend on (python-auth-helper version 2.4.1) has been compromised. A malicious version was published 3 days ago and your CI/CD pipeline installed it during yesterday's build.

  1. What are your immediate actions? List them in order of priority.
  2. How do you determine which systems are affected?
  3. What evidence do you need to collect?
  4. How do you contain the compromise?
  5. What is your communication plan (internal and external)?
  6. How do you determine whether data was exfiltrated?
  7. What changes do you make to prevent recurrence?
  8. Draft a one-page incident summary for leadership.

Deliverable: Prioritized action plan, evidence collection checklist, communication plan, and incident summary.

Exercise 34.13: in-toto Layout Verification

Difficulty: Advanced Objective: Implement in-toto supply chain verification for a simple project.

  1. Install the in-toto Python tools: pip install in-toto
  2. Create a simple software project with three supply chain steps: code, review, build.
  3. Define an in-toto layout that requires: - The developer writes code (signed with developer key) - The reviewer approves code (signed with reviewer key) - The CI builds the artifact (signed with CI key)
  4. Generate link metadata for each step.
  5. Verify the complete supply chain with in-toto-verify.
  6. Test a scenario where a step is skipped. Confirm verification fails.
  7. Test a scenario where an unauthorized person performs a step. Confirm verification fails.

Deliverable: in-toto layout file, link metadata files, verification results for both valid and invalid scenarios.

Exercise 34.14: Package Registry Security Comparison

Difficulty: Intermediate Objective: Compare the security features of major package registries.

Research and compare the security features of npm, PyPI, Maven Central, and crates.io:

  1. For each registry, document: - Account security (2FA requirements, access controls) - Package signing/verification capabilities - Provenance attestation support - Typosquatting detection/prevention - Vulnerability scanning integration - Package removal/yanking policies - Namespace reservation (scoped packages) - Download statistics and transparency
  2. Create a comparison matrix.
  3. Identify which registry has the strongest security posture and justify your assessment.
  4. For the weakest registry, recommend three improvements that would significantly improve security.

Deliverable: Comparison matrix and analysis document.

Exercise 34.15: Continuous Dependency Monitoring

Difficulty: Intermediate Objective: Set up continuous dependency monitoring for a project.

  1. Create or fork a project with known vulnerable dependencies.
  2. Set up Dependabot (GitHub) or Renovate to automatically detect and propose updates for vulnerable dependencies.
  3. Configure the tool to open pull requests for security updates.
  4. Set up OWASP Dependency-Track to continuously monitor the project's SBOM.
  5. Configure alerting for new critical and high-severity vulnerabilities.
  6. Simulate a new vulnerability disclosure: add a dependency with a known CVE and verify the monitoring tools detect it.
  7. Document the end-to-end process from vulnerability disclosure to remediation.

Deliverable: Configuration files for monitoring tools, screenshots of alerts, and process documentation.