Chapter 4 — Programming I
Lesson map
Lesson 04 published. Map, example, EX010.
flowchart TD
N0["Learning outcomes"]
N1["4.1 Programs that check input"]
N2["4.2 Errors without leaks"]
N3["4.3 Standard library first"]
N4["Synthesis"]
N0 --> N1 --> N2 --> N3 --> N4
N4 --> EX["Worked example"]
EX --> Q["Exercise EX010"]
Logical drawing
flowchart LR
N0["Learning outcomes"]
N1["4.1 Programs that check input"]
N2["4.2 Errors without leaks"]
N3["4.3 Standard library first"]
N4["Synthesis"]
N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX010"]
[Learning outcomes]
|
v
[4.1 Programs that check input]
|
v
[4.2 Errors without leaks]
|
v
[4.3 Standard library first]
|
v
[Synthesis]
|
v
[Worked example] --> [Exercise EX010]
Learning outcomes
You will (1) write small, readable programs that validate input; (2) handle errors without leaking sensitive detail; (3) use the standard library rather than reinventing security functions.
4.1 Programs that check input
Sofia's first programming course uses Python. Daniel asks her to write a parser for synthetic fare-tap records: card identifier, validator identifier, timestamp and amount. Her first version trusts every field. He gives her malformed lines, such as a negative amount, a timestamp in the future and a card identifier with unexpected characters, and the program either crashes or accepts nonsense. She rewrites it to validate each field against an allow-list pattern and range, rejecting the line with a reason. Input validation at boundaries is one of the most basic secure-design habits, and it starts with the first programs a student writes.
4.2 Errors without leaks
When validation fails, the program must report enough for an operator to fix the problem but not expose secrets or internal details to whoever supplied the input. Sofia separates two messages: a short public error such as invalid record, and a detailed internal log entry with the line number and reason, written to a file with restricted permissions. She avoids printing stack traces to users. Daniel explains that verbose errors in web services have revealed database names, file paths and versions to attackers, giving them a map. Error handling is part of the interface and deserves the same design care.
4.3 Standard library first
Sofia needs random identifiers for test cards. She first uses the random module, then learns that for anything security-relevant Python's secrets module is required, because it draws from the operating system's secure source. She also needs to compare an authentication tag and learns to use hmac.compare_digest. Daniel's rule is simple: use the standard library or a well-maintained package for security functions, read its documentation, and never write a cipher, hash or random generator yourself. Programming skill is shown by composing reliable parts correctly, not by recreating them.
Worked example
Sofia rewrites a fare-record parser with allow-list validation, separate public and internal error messages, and secrets-generated test identifiers.
Synthetic case. Records, formats and identifiers are synthetic.
Errors and limits
Allow-lists need maintenance when formats change. Internal logs can still leak if their permissions or retention are wrong.
Exercises
- EX010 — Three malformed fields. Name three malformed inputs Daniel used to break Sofia's first parser. Rubric: 3 = negative amount, future timestamp, card id with unexpected characters;; 2 = two;; 1 = one;; 0 = none.
- EX011 — Two messages. What two kinds of error message does Sofia produce? Rubric: 3 = short public message and detailed internal log with restricted access;; 2 = both;; 1 = stack trace;; 0 = none.
- EX012 — secrets module. Why must test card identifiers use secrets instead of random? Rubric: 3 = secrets uses the OS secure source; random is predictable;; 2 = secure source;; 1 = no difference;; 0 = none.
Synthesis
Early programs teach security when they validate inputs, keep error details internal and rely on vetted library functions.
Continue studying — chapter 04 of 50
← Chapter 03 (draft) · Course chapter index · Chapter 05 (draft) →