Scan time: 2026-05-03 13:48:12
Overall Score
⚠ This website has serious GDPR deficiencies. Immediate action is required.
GDPR Issues Detected (4):
❌ 7 third-party server(s) outside the EU/EEA — data transfers without legal basis may violate Art. 44–49 GDPR.
Affected servers outside the EU:
❌ 2 tracking service(s) detected — without prior consent (opt-in) this violates Art. 6(1) GDPR.
Detected trackers:
⚠ Third-party cookies are being set — without consent this violates the ePrivacy Directive.
⚠ No Content Security Policy — increased risk of cross-site scripting (XSS) and data theft.
Note: This automated analysis does not replace legal advice. For a complete GDPR assessment, consult a data protection officer.
↓ See detailed results for each category below.
The website uses an encrypted connection (HTTPS).
Latest encryption active (TLS 1.3 — TLSv1.3).
The security certificate is valid (expires 2026-07-08).
Strong encryption method (TLS_AES_256_GCM_SHA384, 256 bit).
HSTS is enabled — the browser is instructed to always use the encrypted connection.
HSTS duration: 31536000 seconds (at least 1 year) — very good.
HSTS also applies to all subdomains (includeSubDomains).
HSTS preload is enabled — browsers know about the encryption before the first visit.
No Content Security Policy (CSP) found. The website has no protection against injected malicious code.
A Content Security Policy (CSP) is a doorkeeper rule for the browser: "Scripts and styles may only be loaded from these allowed sources." Without CSP, injected malicious code (XSS) can freely fetch anything. Start with a simple, secure baseline.
File: .htaccess in the web root
<IfModule mod_headers.c>
Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; font-src 'self' https: data:; object-src 'none'; frame-ancestors 'self'; base-uri 'self'"
</IfModule>⚠ This policy is intentionally pragmatic (allows inline styles since many themes/plugins rely on them). If something breaks after enabling: F12 → Console shows "Refused to load…" — add the affected domain after script-src / img-src.
File: .htaccess in the WordPress root
# BEGIN WebForensik CSP
<IfModule mod_headers.c>
Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; font-src 'self' https: data:; object-src 'none'; frame-ancestors 'self'; base-uri 'self'"
</IfModule>
# END WebForensik CSP⚠ WordPress often loads external scripts (Google Fonts, jQuery CDN, analytics pixel) — if CSP blocks them: open the console, see which domain is blocked, append that domain to "script-src 'self'" separated by a space.
File: functions.php of your CHILD theme
add_action('send_headers', function () {
header("Content-Security-Policy: default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; font-src 'self' https: data:; object-src 'none'; frame-ancestors 'self'; base-uri 'self'");
});⚠ If unsure: start with "Content-Security-Policy-Report-Only" (only monitor, don’t block), watch violations in the console, then switch to enforced mode.
✓ How to verify it works: Open page, F12 → Console — no red "Refused to load…" messages. Network tab → first request → Response Header "content-security-policy" visible.
Referrer-Policy: strict-origin-when-cross-origin (via HTTP-Header).
MIME type protection active (nosniff) — browsers will not misinterpret files.
Invalid X-Frame-Options value: ALLOWALL.
Your X-Frame-Options header has an invalid value. Only "DENY" (no embedding at all) or "SAMEORIGIN" (only your domain) are allowed.
File: .htaccess in the web root
<IfModule mod_headers.c>
Header always set X-Frame-Options "SAMEORIGIN"
</IfModule>⚠ Replace the malformed value. If you want NO embedding at all, use DENY instead of SAMEORIGIN.
File: .htaccess in the WordPress root
<IfModule mod_headers.c>
Header always set X-Frame-Options "SAMEORIGIN"
</IfModule>⚠ Replace the malformed entry.
✓ How to verify it works: F12 → Network → Response Header: value is DENY or SAMEORIGIN.
No Permissions-Policy set. Third-party scripts could access camera, microphone, or location.
Permissions-Policy controls whether scripts (including third-party) may access camera, microphone, location, motion sensors etc. GDPR-relevant because sensitive device APIs can otherwise be reached unnoticed.
File: .htaccess in the web root
<IfModule mod_headers.c>
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), accelerometer=(), gyroscope=(), magnetometer=(), interest-cohort=()"
</IfModule>⚠ "()" at the end means: no caller (not even your own page) may use this API. If you need geolocation (e.g. a map feature): use geolocation=(self) instead of geolocation=(). "interest-cohort=()" disables Google’s FLoC tracking.
File: .htaccess in the WordPress root
<IfModule mod_headers.c>
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), interest-cohort=()"
</IfModule>⚠ Standard WordPress needs none of these APIs. If you use a plugin that needs the camera (QR scanner, video upload), set that API to "(self)".
File: functions.php of your CHILD theme
add_action('send_headers', function () {
header('Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), interest-cohort=()');
});⚠ Back up functions.php before edits.
✓ How to verify it works: F12 → Network → Response Header: "permissions-policy" visible.
7 first-party and 1 third-party cookie(s).
1 third-party cookie(s) detected. These can be used to track you across different websites.
Third-party cookies (e.g. from Google, Facebook) track visitors across websites. Under GDPR Art. 6 and ePrivacy / national implementations, explicit consent is required BEFORE setting them. Three-step fix: (1) identify which external services set the cookies, (2) remove services you don’t strictly need, (3) for essential services, add a consent banner that loads them only after "Accept".
WordPress plugin: Cookie-consent plugins for WordPress: "Complianz" (free, GDPR-focused, thorough wizard), "Real Cookie Banner" (free, knows many services), "Borlabs Cookie" (paid, most feature-complete). Critical configuration: set all tracking services to "do NOT load before consent" — most plugins detect standard services (GA, Maps, YouTube) automatically.
✓ How to verify it works: Open the site in incognito mode → F12 → Application → Cookies → your-domain.com. BEFORE clicking "Accept" there must be NO cookies from google.com, facebook.com etc. AFTER consent, yes.
1 of 8 cookie(s) without Secure flag — sent over unencrypted connections too.
Cookies without the "Secure" flag are also sent over unencrypted HTTP — and can be intercepted by anyone on the same WLAN. There’s no reason to omit Secure on HTTPS-only sites.
File: .htaccess in the web root
<IfModule mod_headers.c>
Header always edit Set-Cookie "^(.*)$" "$1; Secure" "expr=!(resp('Set-Cookie') -strmatch '*Secure*')"
</IfModule>⚠ This header appends "; Secure" to cookies that don’t have it yet. Requires Apache 2.4+. The cleaner fix is to correct the code that sets the cookie (PHP: session.cookie_secure=1 in php.ini, or setcookie() with "secure" => true).
File: functions.php of your CHILD theme
add_filter('secure_logged_in_cookie', '__return_true');
add_action('init', function () {
if (!headers_sent()) {
@ini_set('session.cookie_secure', '1');
@ini_set('session.cookie_httponly', '1');
@ini_set('session.cookie_samesite', 'Lax');
}
});⚠ Sets the Secure flag for WordPress login cookies and PHP session cookies. Plugins that set their own cookies must be configured separately (check plugin settings).
WordPress plugin: Plugins that set cookies (cache, anti-spam, A/B testing) often have toggles like "Secure cookies" or "HTTPS only" in their settings.
✓ How to verify it works: F12 → Application → Cookies → your-domain.com. The "Secure" column should show a checkmark for every cookie.
4 of 8 cookie(s) without HttpOnly flag — could be read by malicious code.
Cookies without the "HttpOnly" flag can be read by JavaScript — an XSS attacker can steal session cookies and impersonate the logged-in user. Set HttpOnly for all cookies JavaScript doesn’t actively need.
File: .htaccess in the web root
<IfModule mod_headers.c>
Header always edit Set-Cookie "^(.*)$" "$1; HttpOnly" "expr=!(resp('Set-Cookie') -strmatch '*HttpOnly*')"
</IfModule>⚠ Cleaner: set cookies with HttpOnly directly (PHP: setcookie(..., [..., 'httponly'=>true])). Exception: cookies that JS actively reads (e.g. some consent cookies).
File: functions.php of your CHILD theme (or better wp-config.php)
@ini_set('session.cookie_httponly', '1');
@ini_set('session.cookie_secure', '1');⚠ WordPress login cookies have been HttpOnly since 2.x. If you use a plugin that sets session cookies (e.g. WooCommerce cart pre-login), check its settings.
✓ How to verify it works: F12 → Application → Cookies → "HttpOnly" column shows checkmarks everywhere (except for deliberately JS-readable cookies like the consent cookie).
4 of 8 cookie(s) without SameSite protection — sent with requests from other websites.
Without "SameSite" cookies are sent on requests from foreign sites — the basis of CSRF attacks (a foreign page silently triggers actions in your name because the login cookie travels along). Set SameSite=Lax as a minimum.
File: .htaccess in the web root
<IfModule mod_headers.c>
Header always edit Set-Cookie "^(.*)$" "$1; SameSite=Lax" "expr=!(resp('Set-Cookie') -strmatch '*SameSite*')"
</IfModule>⚠ SameSite=Lax is a good default. Strict is safer but breaks external links (user clicks from Google to your site — cookies are NOT sent, login is lost). None allows cross-site but requires "; Secure".
File: wp-config.php (above "/* That’s all, stop editing! */")
@ini_set('session.cookie_samesite', 'Lax');
@ini_set('session.cookie_secure', '1');
@ini_set('session.cookie_httponly', '1');⚠ Sets SameSite/Secure/HttpOnly for PHP session cookies. WordPress login cookies have been SameSite=Lax since WP 6.2. Update older versions!
✓ How to verify it works: F12 → Application → Cookies → "SameSite" column should show "Lax" or "Strict" everywhere, not empty.
| Name | Domain | Encrypted | Server only | SameSite |
|---|---|---|---|---|
| __cf_bm | .calendly.com | Yes | Yes | None |
| _cfuvid | .calendly.com | Yes | Yes | None |
| __stripe_mid | .calendly.com | Yes | No | Strict |
| __stripe_sid | .calendly.com | Yes | No | Strict |
| OptanonConsent | .calendly.com | Yes | No | None |
| _calendly_session | calendly.com | Yes | Yes | Lax |
| _dd_s | calendly.com | No | No | Strict |
| Name | Domain | Encrypted | Server only | SameSite |
|---|---|---|---|---|
| m | m.stripe.com | Yes | Yes | None |
1 localStorage and 0 sessionStorage item(s) found.
| Name | Value |
|---|---|
| _cache | xnEcbQkcIdZXLaJp5sSTMgHHjXXTJLNRLazV/mbZTZw= |
29 request(s) to 10 different third-party servers.
7 third-party server(s) outside the EU/EEA — potentially problematic for GDPR compliance.
GDPR-relevant: visitor data (at least IP + User-Agent) is transmitted to servers outside the EU/EEA. Since the Schrems-II ruling (2020) this requires Standard Contractual Clauses + supplementary technical measures AND prior consent. Best fix: replace with EU alternatives where possible.
WordPress plugin: Common culprits and EU alternatives: Google Fonts → Bunny Fonts or self-host (plugin "OMGF — Host Google Fonts Locally"). Google Analytics → Matomo (self-hosted) or Plausible (EU servers). Google reCAPTCHA → hCaptcha (EU) or Friendly Captcha. Google Maps → OpenStreetMap. YouTube embeds → plugin "WP YouTube Lyte" loads only after click. CDN: Cloudflare → BunnyCDN (EU) or KeyCDN.
✓ How to verify it works: Load in incognito mode, F12 → Network → list all requests → check "Domain" column for non-EU servers. After migration no unrequested US domains should load.
3 third-party server(s) within the EU/EEA.
Requested URLs:
https://cdn.cookielaw.org/scripttemplates/otSDKStub.js
https://cdn.cookielaw.org/consent/a838c8e4-e3ce-442e-8f96-c88d0af98990/a838c8e4-e3ce-442e-8f96-c88d0af98990.json
https://cdn.cookielaw.org/scripttemplates/202508.2.0/otBannerSdk.js
https://cdn.cookielaw.org/consent/a838c8e4-e3ce-442e-8f96-c88d0af98990/0194ae47-f287-77e4-973a-308fa3153bfd/en.json
https://cdn.cookielaw.org/scripttemplates/202508.2.0/assets/v2/otPcPanel.json
https://cdn.cookielaw.org/scripttemplates/202508.2.0/assets/otFloatingRounded.json
https://cdn.cookielaw.org/scripttemplates/202508.2.0/assets/otCommonStyles.css
https://cdn.cookielaw.org/logos/static/ot_guard_logo.svg
https://cdn.cookielaw.org/logos/static/powered_by_logo.svg
https://cdn.cookielaw.org/logos/122ecfc3-4694-42f1-863f-2db42d1b1e68/0e69414e-286b-4e49-b24b-84b4ed6d6ec9/c05bbdff-e7a2-4d14-a37f-28e2f63112d5/logo.png
Requested URLs:
https://www.gstatic.com/recaptcha/releases/gTpTIWhbKpxADzTzkcabhXN4/recaptcha__en.js
https://www.gstatic.com/recaptcha/releases/gTpTIWhbKpxADzTzkcabhXN4/styles__ltr.css
... and 2 more request(s)
Requested URLs:
https://js.stripe.com/v3
https://js.stripe.com/v3/m-outer-3437aaddcdf6922d623e172c2d6f9278.html#url=https%3A%2F%2Fcalendly.com%2Fsendproud%2F30min%2F&title=Calendly&referrer=&muid=NA&sid=NA&version=6&preview=false&__shared_pa
https://js.stripe.com/v3/fingerprinted/js/m-outer-15a2b40a058ddff1cffdb63779fe3de1.js
Requested URLs:
https://www.recaptcha.net/recaptcha/enterprise.js?render=6LeAb4QUAAAAAOM9CNYSsvbnzWTByRAgm3GA5D4n
https://www.recaptcha.net/recaptcha/enterprise/anchor?ar=1&k=6LeAb4QUAAAAAOM9CNYSsvbnzWTByRAgm3GA5D4n&co=aHR0cHM6Ly9jYWxlbmRseS5jb206NDQz&hl=en&v=gTpTIWhbKpxADzTzkcabhXN4&size=invisible&anchor-ms=2000
https://www.recaptcha.net/recaptcha/enterprise/webworker.js?hl=en&v=gTpTIWhbKpxADzTzkcabhXN4
Requested URLs:
https://notifier-configs.airbrake.io/2020-06-18/config/648967/config.json?¬ifier_name=airbrake-js%2Fbrowser¬ifier_version=2.1.9&os=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20App
... and 1 more request(s)
Requested URLs:
https://m.stripe.network/inner.html#url=https%3A%2F%2Fcalendly.com%2Fsendproud%2F30min%2F&title=Calendly&referrer=&muid=NA&sid=NA&version=6&preview=false&__shared_params__[version]=v3
https://m.stripe.network/out-4.5.45.js
Requested URLs:
https://m.stripe.com/6
... and 1 more request(s)
Requested URLs:
https://accounts.google.com/gsi/client
Requested URLs:
https://d3v0px0pttie1i.cloudfront.net/uploads/user/avatar/50613436/99cfe3f3.jpeg
Requested URLs:
https://geolocation.onetrust.com/cookieconsentpub/v1/geo/location
2 known tracker(s) detected! These track visitors across different websites.
Trackers (Google Analytics, Facebook Pixel, …) capture visitors and follow them across multiple sites. Under GDPR Art. 6 and ePrivacy / national implementations, explicit consent is required BEFORE loading the tracker. "Continued scrolling = consent" is NOT acceptable.
WordPress plugin: Consent plugins that properly block trackers until consent: "Complianz" (free, very good), "Real Cookie Banner", "Borlabs Cookie" (paid, most thorough). Principle after setup: do NOT embed the tracker snippet (e.g. GA script) directly in your theme — register it with the consent plugin, which only releases it after "Accept". Privacy-friendly tracker alternatives: Matomo (cookieless mode → may need no consent), Plausible (EU, anonymous, vendor claims no consent needed — legal advice recommended).
✓ How to verify it works: Incognito, load page — BEFORE "Accept": F12 → Network → no requests to google-analytics.com, facebook.com/tr etc. AFTER "Accept", yes.
Google (Anti-fraud): www.recaptcha.net
Google (Content): www.gstatic.com
1 of 6 external resource(s) use integrity verification (SRI).
Only some of your external resources (1 of 6) are protected by SRI. Add integrity attributes to the remaining ones too.
WordPress plugin: Approach: view page source → all <script src="https://…"> and <link href="https://…"> without integrity attribute → generate hash at https://www.srihash.org/ → add integrity="sha384-…" crossorigin="anonymous". Plugin "WP-SRI" automates many cases.
✓ How to verify it works: F12 → Console on page load: no "Failed to find a valid digest" messages. Source: all external <script>/<link> have an integrity attribute.
CAA records present: comodoca.com, digicert.com; cansignhttpexchanges=yes, godaddy.com, letsencrypt.org, pki.goog; cansignhttpexchanges=yes, sectigo.com, ssl.com, amazon.com, comodoca.com, digicert.com; cansignhttpexchanges=yes, godaddy.com, letsencrypt.org, pki.goog; cansignhttpexchanges=yes, sectigo.com, ssl.com, mailto:platform@calendly.com, amazon.com — only specified certificate authorities may issue certificates.
2 nameservers present — good redundancy.
IPv6 support present (AAAA records).
SPF record present: v=spf1 include:%{i}._ip.%{h}._ehlo.%{d}._spf.vali.email include:_spf.google.com include:mktomail.com ~all — protects against email spoofing.
DMARC record present: v=DMARC1; p=quarantine; rua=mailto:dmarc_agg@vali.email — email authentication active.
security.txt found: https://calendly.com/.well-known/security.txt
Contact field present (required) — security researchers can report vulnerabilities.
Expires field present (required).
No external reporting endpoints detected.
Cookie consent system detected: OneTrust, cookielaw.org.
Consent banner is visible to visitors.
Trackers are loaded on page load — possibly BEFORE consent is given.
Your trackers are loaded BEFORE the user can consent ("pre-consent loading"). Common misconfiguration in cookie plugins — banner appears, but too late: the GA script is already running. Violates ePrivacy.
WordPress plugin: Almost always caused by the theme or a tracking plugin that embeds the tracker code directly (e.g. "Google Analytics for WordPress" with auto-insert). Fix: 1) remove tracking code from the theme/plugin. 2) In the consent plugin (Complianz/Real Cookie Banner): register the tracker as a "service", paste the snippet there — the plugin will load it only after consent. 3) ALTERNATIVELY: plugin "PYS PixelYourSite" combined with consent gating. Do NOT rely on "GA anonymized before consent" — legally unsettled and risky.
✓ How to verify it works: Incognito → F12 → Network (clear all, start recording) → load page, do NOT click banner, wait 10 seconds → there must be NO requests to google-analytics.com, googletagmanager.com, facebook.com/tr, doubleclick.net etc.
Privacy policy linked: "Privacy Policy" (https://calendly.com/legal/privacy-notice).
Legal notice linked: "Privacy Policy" (https://calendly.com/legal/privacy-notice).
Privacy policy page is accessible (HTTP 200).
All missing security headers combined into one block. Append this block to the end of your .htaccess — done. 6 headers will be set.
The Content-Security-Policy above deliberately includes 'unsafe-inline' for both style-src and script-src. This does NOT provide full XSS protection — it's a pragmatic trade-off, not a bug.
Why? A typical WordPress setup (theme + 5-15 plugins) emits 10-50 different inline <script> blocks into the HTML: jQuery init, slider init, cookie banner, tracking, GTM, web vitals, lazy-load, speculation rules and so on. A strict script-src 'self' blocks them all — the site becomes visually and functionally broken (blank slider, broken cookie banner, dead plugins).
Consequence for scoring: Sites running WordPress with plugins can score at most ~75-85 points in the CSP category in this app — the full 100% rating is only achievable when inline code is signed via nonce or hash (technically demanding, breaks on every theme/plugin update).
Paths to full XSS protection (in increasing complexity):
Anyone who doesn't take one of these paths lives with 'unsafe-inline' — like about 95% of all production WordPress sites on the web. The other CSP directives still protect: default-src 'self' blocks external resources, object-src 'none' bans Flash/Java, frame-ancestors 'self' prevents clickjacking, base-uri 'self' prevents base-tag hijacking. Not maximum protection, but realistic protection for WP reality.
On Hetzner-Konsoleh webhosting (and comparable shared hosts like All-Inkl, IONOS, Strato, 1blu, …), Apache throws a 500 Internal Server Error as soon as Header always edit Set-Cookie … expr=… appears in .htaccess. The Apache error log says:
Can't parse envclause/expression: syntax error, unexpected T_OP_STR_EQ, expecting $end
This is not a WebForensik bug and not a typo — the shared host has blocked the mod_headers expr= subset via AllowOverride limits (for security, because Header edit could also manipulate cookies of other tenants).
☛ For Hetzner-Konsoleh users: use the variant below marked with the red "Hetzner / Shared" badge. It consists of two files (.htaccess + wp-config.php) instead of one, but avoids the 500 error reliably. Cookie flags go into wp-config.php instead of .htaccess.
Append this block to the end of your .htaccess in the web root — done.
<IfModule mod_headers.c>
Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; font-src 'self' https: data:; object-src 'none'; frame-ancestors 'self'; base-uri 'self'; upgrade-insecure-requests"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), accelerometer=(), gyroscope=(), magnetometer=(), interest-cohort=(), browsing-topics=()"
# Fehlende Cookie-Flags konditional ergänzen (nur wenn nicht schon gesetzt)
Header always edit Set-Cookie "^(.*)$" "$1; Secure" "expr=!(resp('Set-Cookie') -strmatch '*Secure*')"
Header always edit Set-Cookie "^(.*)$" "$1; HttpOnly" "expr=!(resp('Set-Cookie') -strmatch '*HttpOnly*')"
Header always edit Set-Cookie "^(.*)$" "$1; SameSite=Lax" "expr=!(resp('Set-Cookie') -strmatch '*SameSite*')"
</IfModule>
This variant avoids the 500 Internal Server Error on Hetzner-Konsoleh and similar shared hosts (All-Inkl, IONOS, Strato, 1blu …): the .htaccess only contains the header directives (no "Header edit"), cookie flags move into wp-config.php. Two files to edit instead of one, but guaranteed to run.
# BEGIN WebForensik Security
<IfModule mod_headers.c>
Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; font-src 'self' https: data:; object-src 'none'; frame-ancestors 'self'; base-uri 'self'; upgrade-insecure-requests"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), accelerometer=(), gyroscope=(), magnetometer=(), interest-cohort=(), browsing-topics=()"
</IfModule>
# END WebForensik Security
Insert ABOVE the line "/* That's all, stop editing! */". Back up wp-config.php first!
// === WebForensik: Cookie-Hardening (Hetzner-Konsoleh-tauglich) ===
// Bitte OBERHALB der Zeile "/* That's all, stop editing! */" einfügen.
// Wirkt auf PHP-Session- und WordPress-Login-Cookies.
// Plugin-eigene Cookies (z.B. WooCommerce, Cookie-Banner) müssen in den
// Plugin-Einstellungen separat auf "Secure" gestellt werden.
@ini_set('session.cookie_secure', '1');
@ini_set('session.cookie_httponly', '1');
@ini_set('session.cookie_samesite', 'Lax');
if (!defined('FORCE_SSL_ADMIN')) define('FORCE_SSL_ADMIN', true);
Insert this block ABOVE the "# BEGIN WordPress" line, otherwise WP overwrites it on permalink changes.
# BEGIN WebForensik Security
<IfModule mod_headers.c>
Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; font-src 'self' https: data:; object-src 'none'; frame-ancestors 'self'; base-uri 'self'; upgrade-insecure-requests"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), accelerometer=(), gyroscope=(), magnetometer=(), interest-cohort=(), browsing-topics=()"
# Fehlende Cookie-Flags konditional ergänzen
Header always edit Set-Cookie "^(.*)$" "$1; Secure" "expr=!(resp('Set-Cookie') -strmatch '*Secure*')"
Header always edit Set-Cookie "^(.*)$" "$1; HttpOnly" "expr=!(resp('Set-Cookie') -strmatch '*HttpOnly*')"
Header always edit Set-Cookie "^(.*)$" "$1; SameSite=Lax" "expr=!(resp('Set-Cookie') -strmatch '*SameSite*')"
</IfModule>
# END WebForensik Security
If your host disallows .htaccess changes: append this PHP snippet to the end of your CHILD theme's functions.php. Back up first — NEVER edit the parent theme, it gets overwritten on updates.
add_action('send_headers', function () {
header("Content-Security-Policy: default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; font-src 'self' https: data:; object-src 'none'; frame-ancestors 'self'; base-uri 'self'; upgrade-insecure-requests");
header("X-Frame-Options: SAMEORIGIN");
header("Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), accelerometer=(), gyroscope=(), magnetometer=(), interest-cohort=(), browsing-topics=()");
});
// Cookie-Flags für PHP-Session-Cookies — wirkt nur auf $_SESSION,
// NICHT auf von Plugins/Themes per setcookie() gesetzte Cookies.
// Für umfassende Cookie-Absicherung die .htaccess-Variante oben verwenden.
add_action('init', function () {
if (headers_sent()) return;
@ini_set('session.cookie_secure', '1');
@ini_set('session.cookie_httponly', '1');
@ini_set('session.cookie_samesite', 'Lax');
}, 1);
| Header | Value |
|---|---|
| cache-control | max-age=0, private, must-revalidate |
| cf-cache-status | DYNAMIC |
| cf-ray | 9f5f083d3adb913a-FRA |
| content-encoding | br |
| content-type | text/html; charset=utf-8 |
| date | Sun, 03 May 2026 11:47:40 GMT |
| link | <https://assets.calendly.com/assets/booking/css/booking-a8fe825cd.css>; rel=preload; as=style; nopush |
| referrer-policy | strict-origin-when-cross-origin |
| server | cloudflare |
| set-cookie | _calendly_session=br9N1zMXTmHkWG5smAZ6D%2Bpp5Kdjq5CRjN1dHLnhr6KfULn2%2BkSMudfQF%2FVcKkWKyaUeegL%2BN9Yr3n3TBn%2BImlZ5hVg9iM3O4v64EdXUigXviq1VDp8MoVoPTE7MuTxPyWzyc51Kzh%2Fn2Mn0vc%2Fmf%2F8fh8bdPFhHPq%2FVUKU%2FHhZ9KlphO4Q9e7O4U990cr%2FWtVb4sQeGS0LK9Gjr6yyLdlI7%2F7WBZfpiW5sJnJTlAByGXexNHcuOf%2B6Wu9zITKUb |
| strict-transport-security | max-age=31536000; includeSubDomains; preload |
| x-booking-bff-response | true |
| x-content-type-options | nosniff |
| x-frame-options | ALLOWALL |
| x-request-id | be77b8162b3998ed43743fd12887c59c |
| x-runtime | 0.224223 |