Jeremy BryantCybersecurity portfolio

Offline security exercise / source reading

HTTP headers and cookies

Read the supplied instructions here, then download the complete project to use the Python utilities and training materials. These are guided practice materials; reference checks do not assess independent understanding.

Download complete source ZIP

Archive folder: jeremy-bryant-pages/labs/http-header-review/

Lab instructions

labs/http-header-review/README.md

# HTTP headers and cookies

Compare saved response headers and session-cookie attributes with the stated requirements of a fictional museum application. These are original fictional practice cases, not copied coursework or completed professional work.

## Before starting

Prerequisites: HTTP requests/responses and the HTTP log triage lab are helpful. No web server, browser automation or prior application-security experience is required. Use Python 3.10+ with the standard library. Run the commands from this lab folder. The learner reads evidence, makes decisions and edits a worksheet; programming is not required.

Allow **30-45 minutes** for the first guided pass: 5 minutes for vocabulary and scope, 15 for prediction, 10 for checking and correction, and 5-15 for explanation. Changed and later recall exercises are separate practice. Personal completion and independent competence have not been assessed.

## Vocabulary

**HSTS:** a browser policy delivered over HTTPS. **CSP:** Content-Security-Policy. **frame-ancestors:** the CSP control used here for permitted framing. **Secure:** a cookie transport restriction. **HttpOnly:** restricts script access to a cookie. **SameSite:** a cookie sending constraint. **no-store:** a cache storage directive.

## Evidence and exact input model

Readable synthetic response-header blocks plus application requirements and per-response HTML, session and private-data context.

Each case has exactly `schema_version: 1`, `lab_id: "http-header-review"`, `case_id` (`guided`, `changed`, `challenge`), `title`, `synthetic: true`, `context`, `data`, `artifacts`. `context.question` is nonempty text. Objects reject unknown/missing fields; record IDs are unique lowercase names. Read the [shared file and command contract](../FOUNDATION-CONTRACT.md). Files are small UTF-8 JSON; readable artifacts are supplied through prepare where relevant.

`data.requirements` contains `hsts_min_seconds` (positive integer), `frame_ancestors` (`'none'` or `'self'`), `session_cookie` (case-sensitive token name), and `cookie_samesite` (`Strict` or `Lax`). `data.responses` records have `id`, `scheme` (`http`/`https`), boolean `is_html`, `requires_session`, `private_data`, and `headers` (LF-separated fields without a status line). JSON is authoritative; `artifacts.headers.txt` is a required exact mirror. Header names are case-insensitive; repeated Set-Cookie is allowed but repeated cookie names are rejected. Other duplicate headers, folded fields, controls and empty values are rejected. Unknown header names are ignored. HSTS supports max-age and optional includeSubDomains. CSP supports only default-src and frame-ancestors, each with one quoted self/none source. Cookies support simple alphanumeric/underscore/hyphen values and Path=/, Secure, HttpOnly, SameSite. Cache-Control supports no-store, private, public, no-cache, max-age=N. Duplicate or unsupported directives/attributes are errors, not safe results.

## Decision vocabulary

Use `meets-supplied-requirements` if there are no gaps. Otherwise use `requirement-gaps:` followed by applicable comma-separated tokens in this order: `https-required` (HTTP response), **or** `hsts-duration` (HTTPS with absent/short HSTS); `nosniff`; `frame-ancestors` (HTML only); `cache-no-store` (private data only); `session-cookie` (required cookie missing), **or** `cookie-secure`, `cookie-httponly`, `cookie-samesite` for its missing/wrong attributes.

Every response requires HTTPS and nosniff. HTML requires the exact supplied frame-ancestors value; default-src is not its substitute. Private data requires no-store, not merely private. Required sessions need the named cookie and both flags plus the exact supplied SameSite value. The parser is deliberately narrower than browser syntax.

## Run the practice

Use a new attempt number if the destination already exists. Prepare writes only beneath this lab's ignored `run/` folder and refuses existing or linked paths.

```console
python lab.py cases
python lab.py prepare --scenario guided --out run/attempt-01
python lab.py show --case run/attempt-01/case.json
```

Read the case and its readable evidence. Before viewing the analysis, edit `run/attempt-01/answers.json`: replace every blank decision with an exact label above, write `explanation` as a paragraph, and put record/field/line references in the `evidence` list. Keep predictions, uncertainty, next check and help used in `notes.txt`. JSON strings use double quotes; do not add comments or trailing commas. An evidence entry can be a record ID plus the relevant field name.

```console
python lab.py check --case run/attempt-01/case.json --answers run/attempt-01/answers.json
python lab.py analyse --case run/attempt-01/case.json
python lab.py prepare --scenario changed --out run/attempt-02
python lab.py prepare --scenario challenge --out run/attempt-03
python lab.py verify
python test_lab.py
```

Repeat show/check/analyse with the new attempt path. Default case is `fixtures/guided.json` beside the script. Explicit input paths are relative to your current directory; prepare output is relative to this lab. Exit 0 means command success or matching decision fields, 1 means differences/incomplete worksheet, and 2 means invalid input or a filesystem error. Analyse shows the reference reasoning and should stay closed until a prediction is saved. Verify compares three shipped fixtures with fixed reference outputs; it does not assess a learner. Check requires prose and references but cannot judge their accuracy.

## Deliverable and handover

A configuration review stating each requirement gap, the exact field that supports it, a proposed correction and a parser limitation. Keep your first prediction and correction in the notes. Include an honest help-used statement. Use [the worked example](WORKED-EXAMPLE.md) for the guided case and [the drills](DRILLS.md) to reduce prompts over time.

Handover prompt: "What did you observe, which exact evidence supports it, what remains uncertain, and what narrow check should happen next?" A person should review your reasoning and an unfamiliar case before treating the practice as independently demonstrated.

## Limits and primary references

- Results compare supplied response excerpts with a fictional application policy, not with every browser rule or security requirement.
- The narrow parser rejects folding, duplicate singleton fields and unsupported cookie/CSP/HSTS forms; no browser, server or network is used.

Runtime is offline: no external target, packet transmission, email action or host configuration change occurs. All addresses and names are reserved fictional examples. The local decision rules are teaching choices; the references explain underlying concepts, not a claim of tool certification.

- [OWASP Secure Headers Project](https://owasp.org/projects/secure-headers-project)
- [IETF RFC 6265, sections 4.1.2.5-6: Secure and HttpOnly](https://www.rfc-editor.org/rfc/rfc6265.html#section-4.1.2.5)
- [IETF RFC 6797: HTTP Strict Transport Security](https://www.rfc-editor.org/rfc/rfc6797.html)
- [W3C CSP3 working draft: frame-ancestors](https://www.w3.org/TR/CSP3/#directive-frame-ancestors)

Worked example

labs/http-header-review/WORKED-EXAMPLE.md

# Worked example: HTTP headers and cookies

Use this only after saving a first prediction for guided. It explains one case; matching it does not establish independent performance.

## Read, calculate, interpret

`booking` is HTTPS. Its HSTS max-age equals the required 31536000 seconds, nosniff is present, frame-ancestors is none, private content has no-store, and the session cookie has Secure, HttpOnly and SameSite=Strict. Record `meets-supplied-requirements`. This describes the supplied policy only.

`account` sets HSTS max-age to zero, omits frame-ancestors, uses private instead of no-store, omits HttpOnly, and uses Lax where this application requires Strict. Its exact answer is `requirement-gaps:hsts-duration,frame-ancestors,cache-no-store,cookie-httponly,cookie-samesite`. Secure is present, so do not add a Secure gap.

In the written review, pair each proposed change with the requirement that motivates it. For example: "For account, add HttpOnly to the named session cookie because this application requires script access to be restricted." A production change would need compatibility testing; this lab changes no application.

## Check and revise

Run `python lab.py check --case run/attempt-01/case.json --answers run/attempt-01/answers.json`, then reveal `python lab.py analyse --case run/attempt-01/case.json`. Compare decision fields and the reasoning. If a label differs, identify the exact missed input or rule; copying the reference label without explaining the change is not enough.

Keep a short correction in notes: "I first predicted __ because __. The evidence at __ changed that to __. I still cannot conclude __." A matching label can still have a mistaken explanation, so use the handover prompt with another person or teach it back aloud.

Practice drills

labs/http-header-review/DRILLS.md

# Drills: HTTP headers and cookies

## 1. Guided evidence pass

Prepare guided as `run/attempt-01`. Keep WORKED-EXAMPLE closed initially. Read the question, mark scope and evidence sources, then fill every decision and a short explanation. Use the vocabulary if needed and record that help. Allow 30-45 minutes for this first pass.

## 2. Fewer prompts

Work through these questions before opening the analysis:

- Which requirements apply to every response, and which depend on response context?
- Are Secure and HttpOnly answering the same question?
- Why does private not satisfy the supplied no-store requirement?

Check decisions, read the worked example and write one correction with its evidence reference. If every label matched, still explain the hardest choice; a lucky label is not evidence of understanding.

## 3. Independent case

Prepare challenge in a fresh folder. Use challenge without the example. Read the changed frame requirement before judging self. Explain why login has one missing-cookie gap rather than three attribute gaps. Keep the reference files closed until your worksheet and handover are saved. Use the README vocabulary as a glossary if necessary and record that help. Ask another person to examine the reasoning rather than merely the exit code.

## 4. Changed conditions

Prepare changed separately and compare its evidence with guided; keep both attempts. Predict each result before revealing analysis.

- Does an HSTS field on an HTTP response satisfy HTTPS delivery?
- Why can the public non-HTML feed satisfy its requirements without CSP, a session cookie or no-store?
- Would adding every header everywhere prove the application safe? Explain the evidence limit.

Write which fact changed, why the relevant rule changed or did not change, and what remains uncertain. Do not edit the shipped fixture or reference files to make an answer match.

## 5. Teach-back

Explain one response-specific requirement and why a header name alone does not establish its intended effect. Use one record ID and a counterexample. If you need the worked example, say so in the help-used note, then try again later with it closed.

## 6. Later recall

Two days later, list the separate purposes of Secure, HttpOnly and the application SameSite rule. Then reconstruct the difference between private and no-store for this exercise. Record the date, what you recalled unaided, what you checked and one remaining question. This is a practice record, not a claim of complete real-world competence.

## Handover

Submit your own saved worksheet and a short note answering: "What is observed, where is the evidence, what is uncertain, and what should be checked next?" Include initial prediction, correction and help used. No upload or publication is part of this lab.

Browse all 30 lab source pages