◇ OpenCyber Academy
Technologist · Chapter 15 · English

Chapter 15 — Application and software supply chain security: guided lab

Open, free learning for anyone who wants to protect people and technology. No account is required to read this text or its worked answers.

Chapter 15 — Application and software supply chain security: guided lab

Lesson map

Lesson 15 published. Map, example, EX043.

flowchart TD
  N0["Learning outcomes"]
  N1["15.1 The audit"]
  N2["Lab — dependency audit"]
  N3["15.2 Lab result"]
  N4["15.3 Turning results into tasks"]
  N5["15.4 Checking matches"]
  N6["15.5 Prioritisation"]
  N7["Recording the audit"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
  N7 --> EX["Worked example"]
  EX --> Q["Exercise EX043"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["15.1 The audit"]
  N2["Lab — dependency audit"]
  N3["15.2 Lab result"]
  N4["15.3 Turning results into tasks"]
  N5["15.4 Checking matches"]
  N6["15.5 Prioritisation"]
  N7["Recording the audit"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX043"]
[Learning outcomes]
    |
    v
[15.1 The audit]
    |
    v
[Lab — dependency audit]
    |
    v
[15.2 Lab result]
    |
    v
[15.3 Turning results into tasks]
    |
    v
[15.4 Checking matches]
    |
    v
[15.5 Prioritisation]
    |
    v
[Recording the audit]
    |
    v
[Worked example] --> [Exercise EX043]

Learning outcomes

You will (1) run a dependency audit across clients; (2) read advisory matches; (3) total by severity; (4) turn results into tasks.

15.1 The audit

The audit compares each client's installed library versions with a synthetic advisory list, each advisory naming a library, affected versions and severity. Each advisory row gives the lowest affected version and the fixed version, the same form used in the inventory lab. Because the advisory list is synthetic, the lab shows the method without depending on any real feed. The audit is the step that turns the inventory into action. The inventory says which version each project runs; the audit says which of those versions an advisory names. Running it nightly means a newly published advisory is matched against every client by the next morning instead of after days of searching.

Lab — dependency audit

"""Audit all client projects against a synthetic advisory list and summarise by severity."""
projects = {"greenleaf-booking": {"upload-kit": "3.1.0", "forms": "2.2.0"}, "harbour-cafe": {"forms": "2.4.1"},
            "kiteschool-site": {"upload-kit": "3.4.2"}, "museum-tickets": {"upload-kit": "2.9.8", "forms": "2.4.1"}}
adv = [("ADV-7", "upload-kit", "2.0.0", "3.2.0", "high"), ("ADV-8", "forms", "2.0.0", "2.3.0", "medium")]
def v(s): return tuple(map(int, s.split(".")))
count = {}
for p, deps in sorted(projects.items()):
    for aid, pkg, lo, fix, sev in adv:
        if pkg in deps and v(lo) <= v(deps[pkg]) < v(fix):
            print(f"{p:18} {aid} {pkg} {deps[pkg]} -> {fix} ({sev})"); count[sev] = count.get(sev, 0) + 1
print("totals:", count)

Run with python3 lab_audit.py. Verified output:

greenleaf-booking  ADV-7 upload-kit 3.1.0 -> 3.2.0 (high)
greenleaf-booking  ADV-8 forms 2.2.0 -> 2.3.0 (medium)
museum-tickets     ADV-7 upload-kit 2.9.8 -> 3.2.0 (high)
totals: {'high': 2, 'medium': 1}

15.2 Lab result

Greenleaf matches ADV-7 (high) and ADV-8 (medium); museum-tickets matches ADV-7. Totals: high 2, medium 1. The output lists project, library, version and advisory, which is exactly what a developer needs to start. museum-tickets also uses forms 2.4.1, which is above ADV-8's fixed version 2.3.0, so it does not match. harbour-cafe uses the same forms version and is likewise clear. kiteschool-site runs upload-kit 3.4.2, above ADV-7's fix. Each output line gives the fixed version after the arrow, so the developer knows the target without opening the advisory. The totals line tells Aiko how much high-severity work is open at a glance.

15.3 Turning results into tasks

Each match becomes a task with the owner from the inventory and a due date from the severity: high within 7 days, medium within 30. For the lab results, both ADV-7 matches would be due within 7 days and Greenleaf's ADV-8 match within 30. The owner named in the inventory receives the task, so nobody has to decide who should act. Due dates come from the severity in the advisory, adjusted only when context shows the affected feature is unused. Any such adjustment is written on the task with the reason.

15.4 Checking matches

Diego confirms each match by reading the advisory, since version ranges can be written ambiguously. Checking also confirms that the affected feature is actually used. Of the 11 matches in the full audit, one turned out false because the advisory's range excluded the installed patch version. Diego records the reason so the same wording does not mislead the next run. Ambiguity is common at range boundaries, for example whether a range ending at a version includes that version itself. Reading the advisory text settles it before work starts, so developers are not asked to fix projects that were never affected.

15.5 Prioritisation

Where many matches arrive at once, Brightwave may consider exploit likelihood scores such as EPSS (Jacobs et al., 2021) alongside severity and client context. Brightwave has not adopted such scores yet, because its match counts are small enough to handle by severity and context. Diego notes EPSS as an option if a single advisory ever matches many projects at once. Severity remains the starting point; any other score would only change the order within a severity group. Client context, such as Greenleaf's medical notes, still decides which project goes first.

Recording the audit

Each audit run is saved with its date, the advisory list version used and the matches found. When a client asks whether they were affected by an advisory, Brightwave can answer from the record rather than from memory. The record also shows how long each match stayed open, which feeds the remediation-time measure from chapter 9. Diego notices that matches in projects with an active owner close in about four days, while those in projects with no recent work take nearly three weeks, and he raises this with Aiko as a staffing issue.

Worked example

Running the audit across all 23 client projects returns 11 matches. Diego confirms 10; one is a false match because the advisory's range excludes the installed patch version. Corrected matches become tasks, and all highs are fixed within six days.

Synthetic case. Advisories and matches are synthetic.

Errors and limits

Audits only find known advisories; they say nothing about unknown flaws.

Exercises

Synthesis

Audit, confirm, assign and fix by severity.

Continue studying — chapter 15 of 30

← Chapter 14 (draft) · Course chapter index · Chapter 16 (draft) →

Worked answers

EX043. High 2, medium 1.

EX044. High within 7 days, medium within 30.

EX045. The advisory's range excluded the installed patch version.