Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Security headers: verify static, server-rendered, and error responses independently

Last updated: 5 Oct 20266 min read
tutorial
AdvancedBy AITrove Editorial

Security controls are delivered on HTTP responses, so their coverage follows the actual response producer. A static asset, a server-rendered document, an API error, and a redirect may take different paths through a hosting platform. A configuration file that decorates static assets can leave function responses untouched. Define the required headers per response class, then probe the public hostname and record the response source. Check the final response after redirects; a development server can use different middleware and must not stand in for production evidence. Some headers should vary by route rather than being copied blindly onto every response.

Operational decision

A portal deploys static CSS and server-rendered lesson HTML. The static asset responds with a policy header, but the lesson route is generated by a server function and lacks it. The release gate samples one static asset, one lesson, one API error, and one missing-route response through the public hostname. The function attaches the intended policy itself, while the static rule remains responsible for assets. The operator compares headers after following redirects and checks that a cache does not retain a weaker earlier response. When a new route type is added, it joins this response-class matrix before the team calls the policy complete.

bash
set -euo pipefail
: "${SITE_ORIGIN:?set the public origin}"
: "${STATIC_ASSET_PATH:?set a deployed asset path}"
headers=$(mktemp)
trap 'rm -f "$headers"' EXIT
for route in /devops/getting-started "$STATIC_ASSET_PATH" /missing-release-probe; do
  status=$(curl --silent --show-error --location --output /dev/null --dump-header "$headers" --write-out '%{http_code}' "${SITE_ORIGIN}${route}")
  printf '%s status=%s policy=' "$route" "$status"
  awk 'BEGIN { policy = "missing" } /^HTTP\// { policy = "missing" } tolower($0) ~ /^content-security-policy:/ { policy = $0 } END { print policy }' "$headers"
done

Cost and verification

The probe makes one request per response class, so testing C classes costs O(C) requests and header bytes. The sample is an inspection aid, not a pass/fail gate: a missing CSS path or an error response might intentionally use a different policy. A production gate should assert the expected status and headers for each named route, including no-store on private responses. Large header sets add response bytes; more serious is false confidence from checking only the static homepage while server-rendered pages remain unprotected.

Common Mistakes

  • Do not assume a static header rule covers server functions.
  • Do not inspect only the first redirect response.
  • Do not mark a security policy complete after probing one route type.

Connected lessons

Practice and check

devops
browser-security
Storage details