◇ OpenCyber Academy
Engineering · Chapter 9 · English

Chapter 9 — Programming II

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 9 — Programming II

Lesson map

Lesson 09 published. Map, example, EX025.

flowchart TD
  N0["Learning outcomes"]
  N1["9.1 Schema without payloads"]
  N2["9.2 Idempotent upserts"]
  N3["9.3 Property tests for zones"]
  N4["Practice note"]
  N5["9.1b Schema evolution without downtime"]
  N6["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6
  N6 --> EX["Worked example"]
  EX --> Q["Exercise EX025"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["9.1 Schema without payloads"]
  N2["9.2 Idempotent upserts"]
  N3["9.3 Property tests for zones"]
  N4["Practice note"]
  N5["9.1b Schema evolution without downtime"]
  N6["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> Q["EX025"]
[Learning outcomes]
    |
    v
[9.1 Schema without payloads]
    |
    v
[9.2 Idempotent upserts]
    |
    v
[9.3 Property tests for zones]
    |
    v
[Practice note]
    |
    v
[9.1b Schema evolution without downtime]
    |
    v
[Synthesis]
    |
    v
[Worked example] --> [Exercise EX025]

Learning outcomes

You will (1) design a schema for OT findings that forbids exploit recipes; (2) implement idempotent updates keyed by asset and weakness; (3) property-test zone rules.

9.1 Schema without payloads

Store title, asset, zone, weakness class, evidence hash, consequence bound, protective layers intact, status. Reject fields named payload, shell or exploit. Evidence lives in a sealed store; the ticket holds the hash.

Lena's schema rejects a record outright if a forbidden field appears, rather than stripping it quietly, so the person who submitted it learns not to. Consequence bounds and intact protective layers are separate fields, which lets the safety engineer filter findings that touch SIS-B. The evidence hash links each ticket to its sealed proof without copying any of it into the ticket system.

9.2 Idempotent upserts

Two scanners reporting the same open Modbus write on PLC-A must become one finding. Fingerprint = (asset, weakness class, register-or-path). Retries and re-imports leave one row.

Lena tests this by importing the same scanner output twice and by importing two scanners' reports of the same issue; both cases must leave exactly one finding. The fingerprint uses the register or path, not the scanner's own wording, because two tools describe the same weakness differently. When fingerprints collide for genuinely different problems, a person splits them and records why.

9.3 Property tests for zones

State: "for every host in the office zone and every SIS register, permit is false". Generate synthetic hosts and assert. Property tests catch the bug where a new office subnet was added to inventory but not to the deny side of the allow-list.

Synthetic case — Ashford Batch Plant. After the FW-12 finding, Lena added a property test: no L4 host may have a permit path to L1-SIS. CI runs it on every firewall-export change.

The test runs on synthetic hosts drawn from the inventory.

9.4 Errors and limits

Schemas drift; version them. Property generators that never emit the new subnet miss the bug they were written to catch — include inventory diffs as inputs.

Lena feeds the property test with the latest inventory diff, so every new subnet is tested in the next run. The schema has a version field, and older records are migrated with a recorded script rather than edited by hand. When a test is changed, she checks that it still fails on the original bug, since a property that can no longer fail protects nothing.

Practice note

When someone asks for a "just this once" exception host, require a time-boxed exception object in the schema with an expiry and an owner. Exceptions without expiry become permanent conduits.

9.1b Schema evolution without downtime

When the CNHP finding schema gains a required field, such as the work-permit number, deploy a two-phase change: first accept and persist the field as optional while backfilling; then flip the validator to required. Windows mid-flight must not break because a mobile client is one version behind. Publish the schema version in API responses so the field tablets and the monitor's exporter can refuse to write when incompatible. Bulk imports from scanners must pass the same validation path as interactive creates, including forbidden-field checks, or payloads will sneak in through the trusted import side door.

Exercises

Synthesis

Schemas, idempotency and properties keep OT security tooling boring — in the good sense.

Continue studying — chapter 09 of 50

← Chapter 08 (draft) · Course chapter index · Chapter 10 (draft) →