Full checker, method, and sources

Website security header check

Check supplied response headers or run a same-origin bookmarklet on your own website. Review HTTPS, header presence, and observed HTTP resource hosts.

Free. No signup. Your entries stay in this browser.

Run the check on your own website

Drag this link to your bookmarks bar. Open your own page, then run the bookmark. Some browsers or site policies block bookmarklets.

BCT header observation

Read or copy the console snippet
(async function securitySnapshot() {
	let response = null;
	try {
		response = await fetch(location.href, {
			method: "HEAD",
			credentials: "same-origin",
			redirect: "error",
			cache: "no-store"
		});
	} catch {}
	const names = [
		"strict-transport-security",
		"content-security-policy",
		"x-content-type-options",
		"referrer-policy",
		"permissions-policy"
	];
	const mixed = performance.getEntriesByType("resource").filter((resource) => resource.name.startsWith("http:")).map((resource) => {
		try {
			return new URL(resource.name).host;
		} catch {
			return "Unparsed host";
		}
	});
	const summary = [
		"BCT same-origin header observation",
		`Origin ${location.origin}`,
		`HTTPS ${location.protocol === "https:" ? "yes" : "no"}`,
		`HEAD response ${response?.status ?? "Unavailable. The site may block HEAD requests or redirect the page. Use the public header paste box instead."}`,
		...names.map((name) => `${name}: ${response?.headers.get(name) ?? "Not observed"}`),
		`Observed HTTP resource hosts ${[...new Set(mixed)].join(", ") || "None"}`,
		"Header presence does not prove a secure configuration. HEAD can differ from GET. Blocked or upgraded mixed content may not appear in resource timing. No penetration test was performed."
	].join("\n");
	const panel = document.createElement("dialog");
	panel.setAttribute("aria-label", "Website security header observation");
	panel.style.cssText = "max-width:min(90vw,780px);max-height:85vh;background:white;color:#090d14;padding:24px;font:16px/1.5 system-ui;overflow:auto";
	const text = document.createElement("pre");
	text.textContent = summary;
	text.style.cssText = "white-space:pre-wrap;overflow-wrap:anywhere;font:inherit";
	const copy = document.createElement("button");
	copy.textContent = "Copy summary";
	copy.onclick = async () => {
		try {
			await navigator.clipboard.writeText(summary);
			copy.textContent = "Summary copied";
		} catch {
			copy.textContent = "Select the text above to copy";
		}
	};
	const close = document.createElement("button");
	close.textContent = "Close";
	close.onclick = () => {
		panel.close();
		panel.remove();
	};
	panel.append(text, copy, close);
	document.body.append(panel);
	panel.showModal();
	return {
		summary,
		status: response?.status ?? null,
		mixedHosts: [...new Set(mixed)]
	};
})()

Or paste a public header response

Exclude Set-Cookie, authorization, and secret values. Only named security headers appear in the result link.