{"id":13426,"date":"2026-08-31T15:31:15","date_gmt":"2026-08-31T13:31:15","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/toolbox\/http-security-header-checker\/"},"modified":"2026-08-31T15:31:15","modified_gmt":"2026-08-31T13:31:15","slug":"http-security-header-checker","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/http-security-header-checker\/","title":{"rendered":"HTTP Security Header Checker"},"content":{"rendered":"<div class=\"gtm-analyser-container\" style=\"background: var(--bg-panel, #1e1e24); padding: 25px; border-radius: 8px; border: 1px solid var(--border, #2a2a35);\">\n<p style=\"color: var(--text-secondary, #a0a0b0); margin-bottom: 20px;\">Security headers are easy to set and easy to set uselessly. A Content-Security-Policy that permits unsafe-inline is present and does nothing against the attack it exists for. This reads what an address actually sends back and judges the effect, not the presence.<\/p>\n<div style=\"margin-bottom: 14px;\">\n        <label for=\"hc-url\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Address<\/label><br \/>\n        <input id=\"hc-url\" type=\"text\" value=\"https:\/\/example.com\/\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; box-sizing: border-box; font-family: monospace;\">\n    <\/div>\n<p style=\"color: var(--text-secondary, #a0a0b0); font-size: 0.82rem; margin-bottom: 16px;\">The address is fetched once from this server, with a plain GET and no cookies. Requests to private networks, to loopback and to link-local addresses are refused, including through redirects. The query is protected by reCAPTCHA v3; the calling IP address and the target are stored for one hour to limit the rate.<\/p>\n<p>    <button id=\"hc-btn\" class=\"button\" style=\"background: var(--accent, #7ee787); color: var(--on-accent, #0b1114); border: none; padding: 12px 24px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Check the headers<\/button><\/p>\n<div id=\"hc-ausgabe\" style=\"margin-top: 22px;\"><\/div>\n<\/div>\n<p><script>\n(function () {\n    'use strict';<\/p>\n<p>    const T = {\"einleitung\":\"Security headers are easy to set and easy to set uselessly. A Content-Security-Policy that permits unsafe-inline is present and does nothing against the attack it exists for. This reads what an address actually sends back and judges the effect, not the presence.\",\"label_url\":\"Address\",\"datenschutz\":\"The address is fetched once from this server, with a plain GET and no cookies. Requests to private networks, to loopback and to link-local addresses are refused, including through redirects. The query is protected by reCAPTCHA v3; the calling IP address and the target are stored for one hour to limit the rate.\",\"knopf\":\"Check the headers\",\"laeuft\":\"Fetching the headers...\",\"h_uebersicht\":\"Overview\",\"zeile_endziel\":\"Landed at\",\"zeile_status\":\"Status\",\"zeile_spruenge\":\"Redirects\",\"zeile_rahmen\":\"Framing protection\",\"zeile_dauer\":\"Took\",\"ampel_gut\":\"in force\",\"ampel_teilweise\":\"present, weakened\",\"ampel_fehlt\":\"missing\",\"urteil_geschlossen\":\"All four carry weight.\",\"urteil_halb\":\"Some are set, and at least one of them does not do what it looks like it does.\",\"urteil_offen\":\"None of the four is in force.\",\"h_csp\":\"Content-Security-Policy\",\"csp_keine\":\"No policy. Any script the page loads runs, wherever it comes from.\",\"csp_nur_bericht_hinweis\":\"This policy is set report-only. It reports violations and prevents nothing.\",\"h_hsts\":\"Strict-Transport-Security\",\"hsts_keine\":\"No HSTS. The first request over http reaches the server before any redirect can help.\",\"zeile_maxage\":\"max-age\",\"einheit_sekunden\":\"seconds\",\"einheit_tage\":\"days\",\"h_kopfzeilen\":\"The headers as sent\",\"kopfzeilen_keine\":\"None of the relevant headers is present.\",\"h_cookies\":\"Cookies from the response\",\"spalte_name\":\"Name\",\"h_befunde\":\"Findings\",\"ja\":\"yes\",\"nein\":\"no\",\"wert_keiner\":\"none\",\"wert_leer\":\"empty\",\"fehler_kein_token\":\"The check could not be started because reCAPTCHA did not load.\",\"fehler_captcha\":\"reCAPTCHA classified the request as automated. Reloading the page normally helps.\",\"fehler_zu_viele\":\"The limit of {limit} checks per hour for this address has been reached.\",\"fehler_adresse\":\"That address cannot be used.\",\"fehler_zaehler\":\"The rate counter is unavailable, so nothing was fetched.\",\"fehler_pruefdienst\":\"The reCAPTCHA service could not be reached.\",\"fehler_aufbau\":\"The service is not configured correctly. The fault is on this side.\",\"fehler_eingabe\":\"The request could not be read.\",\"fehler_methode\":\"Wrong request method.\",\"fehler_netz\":\"The service could not be reached.\",\"fehler_antwort\":\"The answer could not be read.\",\"fehler_abruf\":\"The address could not be fetched.\",\"fehler_unbekannt\":\"Something went wrong that has no message of its own.\",\"grund_leer\":\"Nothing was entered.\",\"grund_zu_lang\":\"The address is too long.\",\"grund_unlesbar\":\"It does not parse as a web address.\",\"grund_schema\":\"Only http and https are fetched.\",\"grund_benutzerinfo\":\"Addresses with credentials in them are refused.\",\"grund_kein_punkt\":\"The host name needs at least one dot.\",\"grund_hostform\":\"The host name has an unusable form.\",\"grund_port\":\"Only ports 80, 443, 8080 and 8443 are fetched.\",\"grund_gesperrter_bereich\":\"That address points into a private or reserved network. Those are never fetched, not even through a redirect.\",\"grund_kein_dns\":\"The host name does not resolve.\",\"grund_zu_viele_spruenge\":\"Too many redirects.\",\"befund_csp_fehlt\":\"No Content-Security-Policy. Nothing limits where scripts may come from.\",\"befund_csp_unsafe_inline\":\"script-src permits \\u0027unsafe-inline\\u0027. Inline script is exactly what a cross-site scripting attack injects, so the policy is present and toothless against the thing it exists for.\",\"befund_csp_unsafe_eval\":\"script-src permits \\u0027unsafe-eval\\u0027. A string can then become code again, which reopens one of the routes the policy closes.\",\"befund_csp_platzhalter\":\"A script source is a wildcard - *, https: or data:. That permits practically every origin.\",\"befund_csp_nonce_neben_inline\":\"A nonce stands next to \\u0027unsafe-inline\\u0027. Browsers that understand the nonce ignore unsafe-inline; older ones do not. The weaker rule then decides for part of the audience.\",\"befund_csp_ohne_frame_ancestors\":\"No frame-ancestors. The page may be framed unless X-Frame-Options says otherwise.\",\"befund_csp_ohne_object_src\":\"No object-src. \\u0027none\\u0027 there is cheap and closes plugin content as a route.\",\"befund_csp_ohne_skriptregel\":\"Neither default-src nor script-src. The policy says nothing about scripts.\",\"befund_csp_nur_bericht\":\"The policy is report-only. It prevents nothing.\",\"befund_hsts_fehlt\":\"No Strict-Transport-Security. A first call over http reaches the server before the redirect can act.\",\"befund_hsts_kurz\":\"max-age is under six months. Browsers forget the rule again before it can help much.\",\"befund_hsts_ohne_subdomains\":\"Without includeSubDomains the rule covers this host only. A forgotten subdomain stays reachable over http.\",\"befund_rahmen_ungeschuetzt\":\"Neither frame-ancestors nor X-Frame-Options. The page may be embedded in a foreign frame.\",\"befund_xfo_neben_ancestors\":\"X-Frame-Options stands next to frame-ancestors. Browsers that understand the policy ignore the older header; the pair is harmless but one of them is dead weight.\",\"befund_referrer_fehlt\":\"No Referrer-Policy. Browsers then apply their own default, and that default differs between them.\",\"befund_referrer_freizuegig\":\"The policy passes the full address on. Paths and query parameters travel to every third party the page loads.\",\"befund_nosniff_fehlt\":\"No X-Content-Type-Options: nosniff. The browser may guess a type other than the one declared.\",\"befund_permissions_fehlt\":\"No Permissions-Policy. Camera, microphone and location stay available to embedded content by default.\",\"befund_server_version\":\"The Server header names a version. That is a free hint for anyone looking for a matching vulnerability.\",\"befund_powered_by\":\"X-Powered-By names a version.\",\"befund_powered_by_da\":\"X-Powered-By is sent at all. It serves no purpose for a visitor.\",\"befund_cookie_ohne_secure\":\"A cookie is set without Secure. It then also travels over an unencrypted connection.\",\"befund_cookie_ohne_samesite\":\"A cookie is set without SameSite. Browsers apply their own default, and it differs between them.\",\"befund_cookie_none_ohne_secure\":\"A cookie carries SameSite=None without Secure. Browsers refuse that combination outright, so the cookie is simply dropped.\"};<\/p>\n<p>    var ENDPUNKT = '\/lw-headercheck.php';\n    var SITEKEY = '6LcrPkEtAAAAAPo1QCOf-IIM2fCL0UfdJz4y2iSY';\n    var HSTS_HALBJAHR = 15768000;<\/p>\n<p>    \/\/ Kopfzeilen, deren Wert die Ausgabe unver\u00e4ndert zeigt.\n    var ZEIGEN = ['strict-transport-security', 'x-frame-options', 'referrer-policy',\n        'permissions-policy', 'x-content-type-options', 'cross-origin-opener-policy',\n        'cross-origin-embedder-policy', 'cross-origin-resource-policy', 'server', 'x-powered-by'];<\/p>\n<p>    \/\/ =========================================================================\n    \/\/ Bewertung - rein\n    \/\/ =========================================================================<\/p>\n<p>    function liste(w) { return Array.isArray(w) ? w : []; }\n    function zahl(w) { return (typeof w === 'number' && isFinite(w)) ? w : null; }<\/p>\n<p>    function bewerten(antwort) {\n        var a = antwort || {};\n        if (a.fehler) {\n            return { fehler: a.fehler, grund: a.grund || null, limit: zahl(a.limit), kette: liste(a.kette) };\n        }\n        var kopf = (a.kopf && typeof a.kopf === 'object' && !Array.isArray(a.kopf)) ? a.kopf : {};\n        var bau = (a.bausteine && typeof a.bausteine === 'object') ? a.bausteine : {};\n        var csp = (a.csp && typeof a.csp === 'object') ? a.csp : null;\n        var hsts = (a.hsts && typeof a.hsts === 'object') ? a.hsts : null;<\/p>\n<p>        var gezeigt = [];\n        ZEIGEN.forEach(function (n) {\n            if (typeof kopf[n] === 'string' && kopf[n] !== '') { gezeigt.push({ name: n, wert: kopf[n] }); }\n        });<\/p>\n<p>        var direktiven = [];\n        if (csp && csp.direktiven && typeof csp.direktiven === 'object') {\n            Object.keys(csp.direktiven).forEach(function (d) {\n                direktiven.push({ name: d, quellen: liste(csp.direktiven[d]) });\n            });\n        }<\/p>\n<p>        return {\n            fehler: null,\n            url: a.url || '', endziel: a.endziel || a.url || '',\n            status: zahl(a.status), dauer: zahl(a.dauer_ms), kette: liste(a.kette),\n            bausteine: {\n                csp: bau.csp || 'fehlt', hsts: bau.hsts || 'fehlt',\n                rahmen: bau.rahmen || 'fehlt', referrer: bau.referrer || 'fehlt'\n            },\n            urteil: a.urteil || 'offen',\n            cspSatz: (kopf['content-security-policy'] || kopf['content-security-policy-report-only'] || null),\n            cspNurBericht: !!(csp && csp.nur_bericht),\n            direktiven: direktiven,\n            hsts: hsts ? {\n                maxAge: zahl(hsts.max_age), subdomains: !!hsts.subdomains,\n                preload: !!hsts.preload,\n                kurz: (zahl(hsts.max_age) === null || hsts.max_age < HSTS_HALBJAHR)\n            } : null,\n            kopfzeilen: gezeigt,\n            cookies: liste(a.cookies),\n            befunde: liste(a.befunde)\n        };\n    }\n\n    \/\/ =========================================================================\n    \/\/ Abruf\n    \/\/ =========================================================================\n\n    function skriptLaden() {\n        return new Promise(function (auf) {\n            if (window.grecaptcha) { auf(true); return; }\n            var s = document.createElement('script');\n            s.src = 'https:\/\/www.google.com\/recaptcha\/api.js?render=' + SITEKEY;\n            s.onload = function () { auf(true); };\n            s.onerror = function () { auf(false); };\n            document.head.appendChild(s);\n            setTimeout(function () { auf(!!window.grecaptcha); }, 8000);\n        });\n    }\n    \/** grecaptcha.ready abwarten - execute ist bei onload noch nicht da. *\/\n    function tokenHolen() {\n        return skriptLaden().then(function (da) {\n            if (!da || !window.grecaptcha || !window.grecaptcha.ready) { return null; }\n            return new Promise(function (auf) {\n                var fertig = false;\n                function einmal(w) { if (!fertig) { fertig = true; auf(w); } }\n                setTimeout(function () { einmal(null); }, 12000);\n                try {\n                    window.grecaptcha.ready(function () {\n                        if (fertig) { return; }\n                        if (!window.grecaptcha.execute) { einmal(null); return; }\n                        window.grecaptcha.execute(SITEKEY, { action: 'headercheck' })\n                            .then(function (t) { einmal(t || null); }, function () { einmal(null); });\n                    });\n                } catch (e) { einmal(null); }\n            });\n        }, function () { return null; });\n    }\n    function abfragen(url) {\n        return tokenHolen().then(function (token) {\n            return fetch(ENDPUNKT, {\n                method: 'POST', headers: { 'Content-Type': 'application\/json' },\n                body: JSON.stringify({ url: url, token: token || '' })\n            }).then(function (r) {\n                return r.json().then(function (j) { return j; }, function () { return { fehler: 'antwort' }; });\n            }, function () { return { fehler: 'netz' }; });\n        });\n    }\n\n    window.LW_TEST = window.LW_TEST || {};\n    window.LW_TEST.HC = { bewerten: bewerten, darstellen: null, ENDPUNKT: ENDPUNKT, ZEIGEN: ZEIGEN, T: T };\n\n    \/\/ =========================================================================\n    \/\/ Oberflaeche\n    \/\/ =========================================================================\n\n    var btn = document.getElementById('hc-btn');\n    var out = document.getElementById('hc-ausgabe');\n    if (!btn || !out) { return; }\n\n    function el(tag, stil, text) {\n        var e = document.createElement(tag);\n        if (stil) { e.setAttribute('style', stil); }\n        if (text !== undefined) { e.textContent = text; }\n        return e;\n    }\n    function wert(id) { var e = document.getElementById(id); return e ? e.value : ''; }\n\n    var UEBERSCHRIFT = 'font-family: \"Nunito Sans\", sans-serif; font-weight: 700; color: var(--text-primary, #e8e8ee); font-size: 0.92rem; margin: 18px 0 8px;';\n    var ZELLE = 'padding: 5px 12px 5px 0; color: var(--text-secondary, #a0a0b0); font-size: 0.87rem;';\n    var ZELLE_WERT = 'padding: 5px 12px 5px 0; color: var(--text-primary, #e8e8ee); font-size: 0.87rem; font-family: monospace; word-break: break-all;';\n    var VORFORM = 'background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-radius: 6px; padding: 10px; color: var(--text-primary, #e8e8ee); font-family: monospace; font-size: 0.78rem; white-space: pre-wrap; word-break: break-all; margin: 0;';\n    var GUT = ' color: #7ee787;';\n    var WARN = ' color: #ffa94d;';\n    var GRAU = ' color: #8a8a99;';\n\n    function farbe(a) { return a === 'gut' ? GUT : WARN; }\n    function gitter(sp) {\n        return el('div', 'display: grid; grid-template-columns: ' + sp + '; gap: 0 18px; align-items: baseline;');\n    }\n    function paar(g, n, w, stil) {\n        g.appendChild(el('div', ZELLE, n));\n        g.appendChild(el('div', ZELLE_WERT + (stil || ''), w));\n    }\n    function kopfZeile(g, sp) {\n        sp.forEach(function (s) {\n            g.appendChild(el('div', ZELLE + ' font-weight: 700; color: var(--text-primary, #e8e8ee);', s));\n        });\n    }\n\n    function darstellen(b, ziel) {\n        ziel.innerHTML = '';\n        if (b.fehler) {\n            var text = T['fehler_' + b.fehler] || T.fehler_unbekannt;\n            if (b.grund &#038;&#038; T['grund_' + b.grund]) { text = text + ' ' + T['grund_' + b.grund]; }\n            if (b.limit !== null) { text = text.replace('{limit}', String(b.limit)); }\n            ziel.appendChild(el('p', ZELLE + WARN + ' margin: 0;', text));\n            return;\n        }\n\n        ziel.appendChild(el('div', UEBERSCHRIFT, T.h_uebersicht));\n        var g = gitter('auto auto');\n        paar(g, T.zeile_endziel, b.endziel);\n        paar(g, T.zeile_status, String(b.status === null ? '-' : b.status));\n        if (b.kette.length > 1) { paar(g, T.zeile_spruenge, String(b.kette.length - 1), WARN); }\n        paar(g, 'Content-Security-Policy', T['ampel_' + b.bausteine.csp], farbe(b.bausteine.csp));\n        paar(g, 'Strict-Transport-Security', T['ampel_' + b.bausteine.hsts], farbe(b.bausteine.hsts));\n        paar(g, T.zeile_rahmen, T['ampel_' + b.bausteine.rahmen], farbe(b.bausteine.rahmen));\n        paar(g, 'Referrer-Policy', T['ampel_' + b.bausteine.referrer], farbe(b.bausteine.referrer));\n        if (b.dauer !== null) { paar(g, T.zeile_dauer, b.dauer + ' ms', GRAU); }\n        ziel.appendChild(g);\n        ziel.appendChild(el('div', 'margin: 10px 0 0; font-size: 0.9rem; font-weight: 700;'\n            + (b.urteil === 'geschlossen' ? GUT : WARN), T['urteil_' + b.urteil]));<\/p>\n<p>        \/\/ --- CSP ---\n        ziel.appendChild(el('div', UEBERSCHRIFT, T.h_csp));\n        if (!b.cspSatz) {\n            ziel.appendChild(el('p', ZELLE + WARN + ' margin: 0;', T.csp_keine));\n        } else {\n            if (b.cspNurBericht) {\n                ziel.appendChild(el('p', ZELLE + WARN + ' margin: 0 0 8px;', T.csp_nur_bericht_hinweis));\n            }\n            ziel.appendChild(el('pre', VORFORM, b.cspSatz));\n            if (b.direktiven.length) {\n                var gd = gitter('auto auto');\n                b.direktiven.forEach(function (d) {\n                    paar(gd, d.name, d.quellen.length ? d.quellen.join(' ') : T.wert_leer, GRAU);\n                });\n                ziel.appendChild(gd);\n            }\n        }<\/p>\n<p>        \/\/ --- HSTS ---\n        ziel.appendChild(el('div', UEBERSCHRIFT, T.h_hsts));\n        if (!b.hsts) {\n            ziel.appendChild(el('p', ZELLE + WARN + ' margin: 0;', T.hsts_keine));\n        } else {\n            var gh = gitter('auto auto');\n            paar(gh, T.zeile_maxage, (b.hsts.maxAge === null ? '-' : b.hsts.maxAge + ' ' + T.einheit_sekunden)\n                + (b.hsts.maxAge !== null ? '  (' + Math.round(b.hsts.maxAge \/ 86400) + ' ' + T.einheit_tage + ')' : ''),\n                b.hsts.kurz ? WARN : GUT);\n            paar(gh, 'includeSubDomains', b.hsts.subdomains ? T.ja : T.nein, b.hsts.subdomains ? GUT : WARN);\n            paar(gh, 'preload', b.hsts.preload ? T.ja : T.nein, GRAU);\n            ziel.appendChild(gh);\n        }<\/p>\n<p>        \/\/ --- Weitere Kopfzeilen ---\n        ziel.appendChild(el('div', UEBERSCHRIFT, T.h_kopfzeilen));\n        if (!b.kopfzeilen.length) {\n            ziel.appendChild(el('p', ZELLE + ' margin: 0;', T.kopfzeilen_keine));\n        } else {\n            var gk = gitter('auto auto');\n            b.kopfzeilen.forEach(function (z) { paar(gk, z.name, z.wert, GRAU); });\n            ziel.appendChild(gk);\n        }<\/p>\n<p>        \/\/ --- Cookies ---\n        if (b.cookies.length) {\n            ziel.appendChild(el('div', UEBERSCHRIFT, T.h_cookies));\n            var gc = gitter('auto auto auto auto');\n            kopfZeile(gc, [T.spalte_name, 'Secure', 'HttpOnly', 'SameSite']);\n            b.cookies.forEach(function (c) {\n                gc.appendChild(el('div', ZELLE_WERT, c.name || '-'));\n                gc.appendChild(el('div', ZELLE + (c.secure ? GUT : WARN), c.secure ? T.ja : T.nein));\n                gc.appendChild(el('div', ZELLE + GRAU, c.httponly ? T.ja : T.nein));\n                gc.appendChild(el('div', ZELLE + (c.samesite ? '' : WARN), c.samesite || T.wert_keiner));\n            });\n            ziel.appendChild(gc);\n        }<\/p>\n<p>        \/\/ --- Befunde ---\n        if (b.befunde.length) {\n            ziel.appendChild(el('div', UEBERSCHRIFT, T.h_befunde));\n            var l = el('ul', 'margin: 0 0 0 18px; padding: 0; color: var(--text-secondary, #a0a0b0); font-size: 0.87rem; line-height: 1.65;');\n            b.befunde.forEach(function (f) {\n                var t = T['befund_' + f];\n                if (t) { l.appendChild(el('li', '', t)); }\n            });\n            ziel.appendChild(l);\n        }\n    }\n    window.LW_TEST.HC.darstellen = darstellen;<\/p>\n<p>    var laeuft = false;\n    btn.addEventListener('click', function () {\n        if (laeuft) { return; }\n        laeuft = true; btn.disabled = true;\n        out.innerHTML = '';\n        out.appendChild(el('p', ZELLE + GRAU + ' margin: 0;', T.laeuft));\n        abfragen(wert('hc-url')).then(function (a) {\n            darstellen(bewerten(a), out); laeuft = false; btn.disabled = false;\n        }, function () {\n            darstellen(bewerten({ fehler: 'netz' }), out); laeuft = false; btn.disabled = false;\n        });\n    });\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Reads the response headers of an address and says what they actually do: a policy with unsafe-inline is present and toothless, an HSTS of five minutes protects nobody, and a missing frame rule is a missing frame rule.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":38,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-tool-base.php","meta":{"footnotes":""},"tags":[91279,91144,91115],"class_list":["post-13426","page","type-page","status-publish","hentry","tag-prywatnosc-danych-pl","tag-devops","tag-web-security"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>HTTP Security Header Checker - Lukas Wojcik - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/http-security-header-checker\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"HTTP Security Header Checker - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Reads the response headers of an address and says what they actually do: a policy with unsafe-inline is present and toothless, an HSTS of five minutes protects nobody, and a missing frame rule is a missing frame rule.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/http-security-header-checker\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/http-security-header-checker\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/http-security-header-checker\\\/\",\"name\":\"HTTP Security Header Checker - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-08-31T13:31:15+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/http-security-header-checker\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/http-security-header-checker\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/http-security-header-checker\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Toolbox\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"HTTP Security Header Checker\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"luky\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"luky\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"HTTP Security Header Checker - Lukas Wojcik - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/http-security-header-checker\/","og_locale":"en_US","og_type":"article","og_title":"HTTP Security Header Checker - Lukas Wojcik - Blog","og_description":"Reads the response headers of an address and says what they actually do: a policy with unsafe-inline is present and toothless, an HSTS of five minutes protects nobody, and a missing frame rule is a missing frame rule.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/http-security-header-checker\/","og_site_name":"Lukas Wojcik - Blog","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/http-security-header-checker\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/http-security-header-checker\/","name":"HTTP Security Header Checker - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-08-31T13:31:15+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/http-security-header-checker\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/http-security-header-checker\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/http-security-header-checker\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Toolbox","item":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/"},{"@type":"ListItem","position":3,"name":"HTTP Security Header Checker"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"luky","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"luky"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/13426","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=13426"}],"version-history":[{"count":0,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/13426\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/38"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=13426"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=13426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}