Settings

The headers

To get them:curl -sSIL https://example.com

Or in the browser: developer tools, Network, pick the page, and copy its response headers. Either the raw view or the tidy one will do.

Why paste the headers instead of typing an address

A header-scanning website fetches the page from its own servers. That only works for a page on the public internet, and it tells the scanner, and whoever it shares its logs with, which address you were looking at. The pages whose headers matter most are usually the ones it cannot reach: the staging copy before launch, the internal admin panel, the application behind a login, the client's system you are testing under an agreement that says the findings stay private.

Headers are text. The server has already sent them to you. Reading them here means the audit covers exactly the response you have, from wherever you got it, and nothing about the site is sent anywhere.

What it checks, and how carefully

  • Content-Security-Policy, the way a browser reads it. Most mistakes in a policy are silent: a missing semicolon turns the next directive into a host name, self without its quotes is a host called self, and a directive written twice keeps only its first copy. Each of those is found rather than trusted. Then the script policy is judged for what it actually lets run: inline script, eval, any host, data:, and hosts where anybody can publish a script or which serve something known to get round an allowlist. A nonce or hash with 'strict-dynamic' is recognised as the strong form it is, and 'unsafe-inline' beside a nonce is recognised as ignored.
  • Strict-Transport-Security. Whether it is valid, whether the period is long enough to matter, and whether a site asking for the browsers' preload list would actually be accepted onto it.
  • Framing. X-Frame-Options and frame-ancestors together, because the second overrides the first, and because ALLOW-FROM looks like protection and is ignored.
  • Cookies. Secure, HttpOnly and SameSite on each one, the __Host- and __Secure- prefixes whose rules a browser enforces by quietly dropping the cookie, and a shared cache told it may keep a response that sets one.
  • Cross-origin reads. Access-Control-Allow-Origin: null, and the wildcard-with-credentials pair browsers refuse, which tends to get "fixed" by echoing any origin back.
  • The rest. X-Content-Type-Options, Referrer-Policy, Permissions-Policy, Cross-Origin-Opener-Policy, headers that name the server's software and version, and retired headers that do nothing now.

What one response cannot tell you

Headers are a promise about what the browser should do, not proof the application is safe. A strong policy on the login page says nothing about the headers on the API behind it, so check the responses that matter, not only the home page. Whether a server copies back any Origin it is sent shows up only by sending it one, and the page says how when it matters. There is no letter grade here, because a grade adds up things that are not the same size: a missing header on a static brochure and inline script allowed on a banking page do not belong on one scale.

For the certificate the site presents, CERTLENS takes it apart. For a token in one of these cookies, JOT reads it. For a copy of the traffic itself, WIRE reads a packet capture and INTERCEPT cleans the secrets out of one before it is shared.

Questions people ask about RAMPART

Why not just use a header scanning website?

Use one if you like, for a public page. It has to fetch the page from its own servers, so it cannot reach a staging site, an intranet application or anything behind a login, and it learns which address you are checking. RAMPART reads headers you already have, so it works on any response and sends nothing anywhere.

How do I get the headers?

From a terminal, curl -sSIL https://the-address prints them, one block for each redirect. In a browser, open the developer tools, go to Network, reload, pick the page and copy its response headers. The raw view and the tidy name-then-value view both work.

Why is 'unsafe-inline' marked as ignored?

When a policy also lists a nonce or a hash, every current browser drops 'unsafe-inline' and runs only the scripts that carry the nonce or match the hash. Leaving it in is the recommended way to keep very old browsers working, so RAMPART counts it as fine in that case and as serious without a nonce or hash.

Why is a CDN in my script-src flagged?

Because trusting a host trusts everything on it. Hosts such as cdn.jsdelivr.net and unpkg.com serve any file anybody publishes to npm or GitHub, and some Google and cdnjs addresses serve old AngularJS or JSONP endpoints that are known ways round an allowlist. Loading the file from your own origin, or moving to nonces with 'strict-dynamic', removes the problem.

Does it give the site a grade?

No. A grade adds together things of very different size: a missing Permissions-Policy on a brochure site and inline script allowed on a payments page are not on one scale. RAMPART sorts what it finds into serious, worth fixing and worth knowing, and says why each one matters and the line that fixes it.

Can it tell whether the server reflects any Origin?

Not from one response. When the headers allow a named origin to read the response, RAMPART says so and gives the curl command that sends a made-up Origin, which is the only way to find out.

Related tools