◇ 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 Modules and interfaces"]
  N2["9.2 Negative tests"]
  N3["9.3 Dependencies"]
  N4["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4
  N4 --> EX["Worked example"]
  EX --> Q["Exercise EX025"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["9.1 Modules and interfaces"]
  N2["9.2 Negative tests"]
  N3["9.3 Dependencies"]
  N4["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX025"]
[Learning outcomes]
    |
    v
[9.1 Modules and interfaces]
    |
    v
[9.2 Negative tests]
    |
    v
[9.3 Dependencies]
    |
    v
[Synthesis]
    |
    v
[Worked example] --> [Exercise EX025]

Learning outcomes

You will (1) structure programs into modules with clear interfaces; (2) write tests including negative tests for security behaviour; (3) manage dependencies safely.

9.1 Modules and interfaces

In Programming II Sofia builds a small fare-rules engine as several modules: parsing, tariff lookup, discount rules and output. Each module exposes a narrow interface and hides its internals. Daniel explains why this matters for security: narrow interfaces are easier to review, and a module that receives only validated data from the parser need not repeat every check. This is economy of mechanism at the code level. When the discount module later needs a change, Sofia can review only its interface and tests rather than the whole program, which reduces the chance of introducing a flaw elsewhere.

9.2 Negative tests

Sofia writes unit tests for normal fares, then Daniel asks for negative tests: inputs that must be rejected. A child discount must not apply to an adult card; a tariff zone outside the network must raise an error; an amount with more than two decimal places must be refused. Security bugs often live in what a program wrongly accepts, so tests should show that bad inputs fail. She runs the tests automatically on every change. Negative tests also document intent: a later developer can see that rejecting those inputs was deliberate and not an accident to be removed.

9.3 Dependencies

Sofia's program uses a third-party package to read configuration files. Daniel shows her how to pin its version, record where it came from and check for published advisories. NIST SP 800-218, the Secure Software Development Framework, recommends practices such as tracking components and responding to vulnerabilities in them. A dependency is code someone else wrote that runs with your program's privileges. Sofia learns to prefer the standard library where it suffices, choose well-maintained packages otherwise and review how much code each new dependency brings, since every line is part of the system's attack surface.

Worked example

Sofia modularises a fare-rules engine, adds three negative tests that must fail safely and pins and records one dependency per SP 800-218 practices.

Synthetic case. The engine and package are synthetic; SP 800-218 is real.

Errors and limits

Tests show presence of checks, not absence of all bugs. Pinned dependencies still need updates when advisories appear.

Exercises

Synthesis

Modular design, negative tests and managed dependencies make programs easier to trust and to keep trustworthy.

Continue studying — chapter 09 of 50

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