guest@websec: ~/websec/12-transport-cookies-third-party — zsh — 100×40 by SaKKo ENTH code:

guest@websec ~ % man 12-transport-cookies-third-party

12 · Transport, Cookies and Third-Party Scripts

Browser-side hardening from Mozilla's checklist: HTTPS, cookies, and not trusting CDNs blindly.

12.1 TLS everywhere

HTTPS for every site, even "static" ones. Plain HTTP pages can be read or changed on the way.

  • Use Mozilla's SSL config generator; "Intermediate" suits most sites.
  • Auto-renew certificates.
  • Test with SSL Labs after changes.

Redirects that keep HSTS working

Go HTTP → HTTPS on the same host first, then to www, so HSTS sticks. APIs: just turn HTTP off.

Mixed content

One http:// script on an HTTPS page undoes it. Load everything over HTTPS.

force_ssl covers redirects and HSTS. Certificates and TLS live at the proxy, not in Rails.

12.2 Cookies: attributes and prefixes

Lock cookies down as tight as possible:

attributewhat it doesrecommendation
Secureonly sent over HTTPSalways
HttpOnlyinvisible to JavaScript (document.cookie)always, unless your JS truly needs to read it
SameSiteStrict: never sent cross-site · Lax: only on top-level GET navigation · None: always (requires Secure)Lax or Strict
Domainomitted = this exact host only; Domain=example.com = every subdomain tooomit it unless you need sharing
Pathlimits which paths receive it (weak isolation)/ or narrower
Expires/Max-Agepersistence; without it, a session cookieshort for sessions
__Host- prefixbrowser rejects the cookie unless Secure, Path=/ and no Domainbest for session cookies
__Secure- prefixbrowser rejects the cookie unless Securefor cookies that need a Domain

Why prefixes? Without them, a forgotten subdomain an attacker takes over can overwrite your cookies. __Host- cookies can only come from your exact host.

sim: cookie builderbuild a Set-Cookie header and get feedback

header

review

Session cookies are already HttpOnly and Lax, and Secure once force_ssl is on. Rename the key to __Host-myapp_session for the prefix.
# config/initializers/session_store.rb
Rails.application.config.session_store :cookie_store, key: "__Host-myapp_session"

# your own cookies (string key: the prefix contains "-")
cookies.encrypted["__Host-prefs"] = { value: { theme: "dark" }, httponly: true,
                                       secure: true, same_site: :strict, expires: 30.days }

12.3 Third-party scripts and Subresource Integrity (SRI)

Every CDN script runs with full access to our page. If the CDN gets hacked, so do we. In 2024, polyfill.io changed owners and started serving malware to more than 100,000 sites.

SRI pins a script to its hash. If the file changes, the browser won't run it.

sim: SRI checkreal SHA-384 in your browser

The page pinned the library when it was added. Then someone modifies the file on the CDN.

  • Self-host scripts where you can.
  • Pin versions and add SRI for CDNs.
  • Limit script sources with CSP.
  • Delete scripts nobody uses.
Importmap and jsbundling serve JS from our own domain, which avoids this. For CDN tags, add integrity: and crossorigin:.

12.4 robots.txt is not a security control

It's public, and attackers read it first. Listing secret paths there just advertises them. Use real auth.