Project-Template/docs/architecture/scripts
null bbf2a0a1ac feat(security): preflight.sh distinguishes present from in force
Run against its first real target the script reported "ok
strict-transport-security present". The response carried two of them:

  strict-transport-security: max-age=63072000; includeSubDomains
  strict-transport-security: max-age=63072000; preload

RFC 6797 section 8.1 -- more than one and the agent MUST process only the first
-- so what was in force was includeSubDomains without preload, and preload had
never once applied while the headers read, to a person, as though the site were
preload-ready. Two layers each adding their own is all it takes, and the second
is discarded in silence.

Each security header is now counted, and more than one is a finding naming the
directives that actually survive.

Two details that each took a wrong answer to get right, both the same class of
error the check exists to catch -- a tool answering confidently and wrongly:

- The value comes from the FIRST occurrence of the FINAL response block. Using
  the last named the second header as the one in force, which is precisely
  backwards, and curl -L concatenates every hop so an unscoped search quotes a
  redirect's copy rather than the page's.
- It is quoted from the original headers rather than the lowercased copy used
  for matching. Reporting `includesubdomains` to somebody who wrote
  `includeSubDomains` shows them a value they never sent.

Verified against a local server serving each shape, and against the origin that
prompted it, where it now names 'max-age=63072000; includeSubDomains' as in
force -- matching the wire byte for byte.

closes #12
2026-08-17 23:30:37 -05:00
..
audit-gate.mjs chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
backup.sh chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
check-env.sh chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
commit-mine.sh chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
controls.sh feat(ops): controls.sh, which controls this project actually has 2026-08-17 23:11:52 -05:00
dead-code.py chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
deploy.py chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
dev.sh chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
doc-claims.sh chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
doc-triggers.py chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
duplication.py chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
forgejo-issue.py chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
healthcheck.sh docs(template): the owner is _null 2026-08-17 22:47:56 -05:00
migrate.sh chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
preflight.sh feat(security): preflight.sh distinguishes present from in force 2026-08-17 23:30:37 -05:00
prove-guard.sh chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
release-notes.mjs chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
release.sh chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
restore-check.sh feat(ops): restore-check.sh, the other half of backup.sh 2026-08-17 23:07:36 -05:00
scaffold.sh feat(docs): OPERATIONS.md, the runbook that did not exist 2026-08-17 22:57:20 -05:00
secrets.sh fix(secrets): the scanner printed the credential it found 2026-08-17 23:08:57 -05:00
status.sh chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00
verify.sh chore(repo): put the template under version control 2026-08-17 22:44:26 -05:00