{"id":518,"date":"2026-10-01T09:20:00","date_gmt":"2026-10-01T07:20:00","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/?page_id=518"},"modified":"2026-09-25T10:49:13","modified_gmt":"2026-09-25T08:49:13","slug":"web-infrastructure-hardening-controlling-third-party-scripts-via-content","status":"publish","type":"post","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/","title":{"rendered":"Web Infrastructure Hardening: Controlling Third-Party Scripts via Content Security Policy (CSP)"},"content":{"rendered":"<h2>Architectural Overview: Attack Vectors of Third-Party Script Injections<\/h2>\n<p>Modern web applications and WordPress installations frequently rely on third-party JavaScript for analytics, tag management, embedded media, and marketing automation. However, every external script source introduced into the Document Object Model (DOM) expands the attack surface. Compromised Content Delivery Networks (CDNs), supply-chain attacks on JavaScript libraries, or malicious browser extensions can silently inject unauthorized scripts into the browsing session.<\/p>\n<p>Without architectural controls at the HTTP header level, browsers execute any script present in the DOM indiscriminately. This creates severe risks of Cross-Site Scripting (XSS), DOM scraping, and unauthorized data exfiltration (e.g., form skimming or cookie theft). Implementing a robust <strong>Content Security Policy (CSP)<\/strong> establishes an immutable permit system within the client browser, ensuring that only explicitly authorized origins and cryptographic hashes are permitted to execute code or transmit data.<\/p>\n<figure class=\"lw-diagram\">\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/diagrams\/csp-third-party-script-control-en.png\" width=\"1120\" height=\"560\" alt=\"Content Security Policy flow: header from Nginx and WordPress, evaluated by the browser into allowed and blocked resources\"><figcaption>How the policy takes effect: the header comes from Nginx, with WordPress as a fallback. The browser then compares every resource against the directives \u2014 <code>googletagmanager.com<\/code> is on the allow list, injected scripts and <code>object<\/code> embeds are not.<\/figcaption><\/figure>\n<h2>Step-by-Step Implementation Guide<\/h2>\n<h3>Step 1: Conducting a Complete Script and Endpoint Audit<\/h3>\n<p>Before deploying an enforcing CSP header, all legitimate domain dependencies must be inventoried. In a standard WordPress v7.0.2 environment equipped with enterprise tag management and server-side tracking, an audit typically identifies the following necessary directives:<\/p>\n<ul>\n<li><code>default-src 'self'<\/code> \u2013 Restricts all fallback resource loading strictly to the primary domain.<\/li>\n<li><code>script-src 'self'<\/code> \u2013 Permits scripts hosted on the primary server domain.<\/li>\n<li><code>connect-src 'self'<\/code> \u2013 Limits REST API, Fetch, and XHR connections to trusted analytics endpoints.<\/li>\n<li><code>img-src 'self' data:<\/code> \u2013 Allows local images and inline base64 data URIs.<\/li>\n<\/ul>\n<h3>Step 2: Designing a Minimal-Privilege CSP Policy<\/h3>\n<p>To prevent tracking script injections while preserving functionality for authorized platforms (such as Google Tag Manager, GA4, Matomo, or a custom Server-Side GTM endpoint), domain allow-lists must be explicitly defined. A secure baseline policy targeting enterprise analytics workloads is structured as follows:<\/p>\n<pre><code>default-src 'self';\nscript-src 'self' 'unsafe-inline' https:\/\/www.googletagmanager.com https:\/\/cdn.matomo.cloud;\nimg-src 'self' data: https:\/\/www.google-analytics.com https:\/\/www.googletagmanager.com;\nconnect-src 'self' https:\/\/www.google-analytics.com https:\/\/region1.google-analytics.com https:\/\/matomo.cloud https:\/\/tracking.lukaswojcik.com;\nframe-src 'self' https:\/\/www.youtube.com;\nobject-src 'none';\nbase-uri 'self';\nform-action 'self';<\/code><\/pre>\n<p><em>Note:<\/em> The use of <code>'unsafe-inline'<\/code> within <code>script-src<\/code> should ideally be replaced by automated cryptographic nonces or SHA-256 script hashes in high-security environments.<\/p>\n<h3>Step 3: Server-Level Deployment via Nginx Configuration<\/h3>\n<p>For optimal performance, CSP headers should be transmitted directly by the web server rather than being generated within the PHP application layer. Adding the policy to the SSL server block in Nginx ensures execution before PHP processing occurs:<\/p>\n<pre><code># \/etc\/nginx\/sites-available\/lukaswojcik.com.conf\nserver {\n    listen 443 ssl http2;\n    server_name www.lukaswojcik.com lukaswojcik.com;\n\n    # Secure CSP Header Enforcement\n    add_header Content-Security-Policy \"default-src 'self'; script-src 'self' 'unsafe-inline' https:\/\/www.googletagmanager.com https:\/\/cdn.matomo.cloud; img-src 'self' data: https:\/\/www.google-analytics.com https:\/\/www.googletagmanager.com; connect-src 'self' https:\/\/www.google-analytics.com https:\/\/region1.google-analytics.com https:\/\/matomo.cloud https:\/\/tracking.lukaswojcik.com; frame-src 'self' https:\/\/www.youtube.com; object-src 'none'; base-uri 'self'; form-action 'self';\" always;\n    \n    add_header X-Content-Type-Options \"nosniff\" always;\n    add_header X-Frame-Options \"SAMEORIGIN\" always;\n}<\/code><\/pre>\n<p>After modifying the Nginx configuration, syntax verification and a graceful service reload are mandatory:<\/p>\n<pre><code>nginx -t &amp;&amp; systemctl reload nginx<\/code><\/pre>\n<h3>Step 4: Application-Level Fallback via WordPress functions.php<\/h3>\n<p>If server-level Nginx access is restricted, the identical CSP header can be dispatched via PHP during the WordPress request lifecycle by integrating the following routine into the active theme&#8217;s <code>functions.php<\/code>:<\/p>\n<pre><code>\/**\n * Content Security Policy Header Enforcement\n * Target: WordPress v7.0.2\n *\/\nadd_action( 'send_headers', 'lw_enforce_content_security_policy' );\n\nfunction lw_enforce_content_security_policy() {\n    if ( ! is_admin() ) {\n        $csp = \"default-src 'self'; \" .\n               \"script-src 'self' 'unsafe-inline' https:\/\/www.googletagmanager.com https:\/\/cdn.matomo.cloud; \" .\n               \"img-src 'self' data: https:\/\/www.google-analytics.com https:\/\/www.googletagmanager.com; \" .\n               \"connect-src 'self' https:\/\/www.google-analytics.com https:\/\/region1.google-analytics.com https:\/\/matomo.cloud https:\/\/tracking.lukaswojcik.com; \" .\n               \"frame-src 'self' https:\/\/www.youtube.com; \" .\n               \"object-src 'none'; \" .\n               \"base-uri 'self'; \" .\n               \"form-action 'self';\";\n        \n        header( 'Content-Security-Policy: ' . $csp );\n    }\n}<\/code><\/pre>\n<h3>Step 5: Quality Assurance and Report-Only Testing<\/h3>\n<p>Before applying strict blocking rules to production traffic, deploying the header as <code>Content-Security-Policy-Report-Only<\/code> is recommended. This logs policy violations to the browser console without blocking script execution.<\/p>\n<p>Verification must be conducted using browser developer tools (F12):<\/p>\n<ol>\n<li><strong>Network Header Inspection:<\/strong> Open the Network tab, reload the page, and confirm that the HTTP response includes the correct <code>Content-Security-Policy<\/code> string.<\/li>\n<li><strong>Console Anomaly Detection:<\/strong> Observe the browser Console tab. Unauthorized tracking tags will trigger explicit red CSP violation errors. Content scripts of browser extensions, by contrast, are not subject to the page&#8217;s CSP; only what they insert into the page as script elements is checked against the policy.<\/li>\n<li><strong>Tracking Endpoint Validation:<\/strong> Verify that server-side tracking calls to custom analytics endpoints execute with HTTP 200 status codes without triggering connection refusals.<\/li>\n<\/ol>\n<h2>Summary and Measurable Added Value<\/h2>\n<p><strong>What is achieved:<\/strong> Uncontrolled execution of arbitrary JavaScript within the DOM is replaced by a cryptographically enforced, domain-level allow-list managed directly by the browser&#8217;s security engine.<\/p>\n<p><strong>Resulting added value:<\/strong><\/p>\n<ul>\n<li><strong>Protection Against Supply-Chain Attacks:<\/strong> Compromised external JavaScript libraries or unauthorized third-party scripts are immediately blocked from executing or exfiltrating data.<\/li>\n<li><strong>GDPR and Privacy Compliance:<\/strong> Unauthorized tracking pixels and piggyback tags are systematically prevented from establishing connections to third-party ad networks.<\/li>\n<li><strong>Form and Session Hardening:<\/strong> Restricting <code>connect-src<\/code> and <code>form-action<\/code> prevents credential harvesting and form skimming across all WordPress pages.<\/li>\n<\/ul>\n<div class=\"lw-faq\">\n<h2>Questions and answers<\/h2>\n<h3>Why is the CSP from the Nginx configuration missing on some URLs?<\/h3>\n<p>Because of how add_header is inherited. Nginx only passes add_header directives from the server block down to location blocks that contain no add_header directive of their own. If a location block for images, fonts or PHP sets its own header such as Cache-Control, all headers from the server block are dropped there, including Content-Security-Policy, X-Content-Type-Options and X-Frame-Options.<\/p>\n<p>This often goes unnoticed for a long time, because the check in step 5 is usually done on an HTML page. A sample per location block is safer, covering images, scripts and the URLs served through PHP as well.<\/p>\n<p>The fix is to repeat the headers in every location block that has add_header lines of its own, most easily through a shared file pulled in with include.<\/p>\n<h3>What happens if both Nginx and functions.php send a CSP?<\/h3>\n<p>Then both apply. The browser does not merge several Content-Security-Policy headers into one policy; it checks every resource against each of them, and only what all of them allow is loaded. A domain listed in only one of the two versions therefore stays blocked. That happens easily when a source is added in one place only, for instance in the Nginx configuration but not in functions.php.<\/p>\n<p>Conversely, the header from functions.php can be missing even though the code is correct. A page cache that serves finished HTML files straight from the web server without starting PHP delivers them without that header unless it stores the headers as well. Anyone setting the policy through PHP should therefore also check a page served from the cache, not just a freshly generated one.<\/p>\n<h3>How can violations that only occur for real visitors be collected?<\/h3>\n<p>Through a reporting address in the policy. The console only shows violations in the browser of whoever is checking; with the report-uri directive, or the newer report-to together with the Reporting-Endpoints header, visitors&#8217; browsers send every violation as JSON to an endpoint run by the site, in Report-Only mode as well. These reports also contain noise, for example from browser extensions, so they are best evaluated by source rather than by sheer count.<\/p>\n<\/div>\n<div class=\"lw-quellen\">\n<h2>Sources<\/h2>\n<ul>\n<li><a href=\"https:\/\/owasp.org\/www-project-top-ten\/\" target=\"_blank\" rel=\"noopener noreferrer\">OWASP Top 10<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/reference\/hooks\/\" target=\"_blank\" rel=\"noopener noreferrer\">WordPress functions.php \/ hooks reference<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Technical tutorial on securing WordPress v7.0.2 installations against unauthorized script injections and tracking pixels by enforcing strict Content Security Policy (CSP) headers.<\/p>\n","protected":false},"author":1,"featured_media":18849,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[120],"tags":[91312,91516,91219,91115,91096],"class_list":["post-518","post","type-post","status-publish","format-standard","hentry","category-tutorials-en","tag-javascript","tag-tracking","tag-tutorial","tag-web-security","tag-wordpress"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Web Infrastructure Hardening: Controlling Third-Party Scripts via Content Security Policy (CSP) | Lukas Wojcik<\/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\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Web Infrastructure Hardening: Controlling Third-Party Scripts via Content Security Policy (CSP) | Lukas Wojcik\" \/>\n<meta property=\"og:description\" content=\"Technical tutorial on securing WordPress v7.0.2 installations against unauthorized script injections and tracking pixels by enforcing strict Content Security Policy (CSP) headers.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-01T07:20:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-518-web-infrastructure-hardening-control-k.png\" \/>\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\/png\" \/>\n<meta name=\"author\" content=\"Lukas Wojcik\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Lukas Wojcik\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/data-privacy\\\/tutorials-en\\\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/data-privacy\\\/tutorials-en\\\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\\\/\"},\"author\":{\"name\":\"Lukas Wojcik\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"headline\":\"Web Infrastructure Hardening: Controlling Third-Party Scripts via Content Security Policy (CSP)\",\"datePublished\":\"2026-10-01T07:20:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/data-privacy\\\/tutorials-en\\\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\\\/\"},\"wordCount\":1028,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/data-privacy\\\/tutorials-en\\\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-518-web-infrastructure-hardening-control-k.png\",\"keywords\":[\"JavaScript\",\"Tracking\",\"Tutorial\",\"Web Security\",\"WordPress\"],\"articleSection\":[\"Tutorials\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/data-privacy\\\/tutorials-en\\\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/data-privacy\\\/tutorials-en\\\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/data-privacy\\\/tutorials-en\\\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\\\/\",\"name\":\"Web Infrastructure Hardening: Controlling Third-Party Scripts via Content Security Policy (CSP) | Lukas Wojcik\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/data-privacy\\\/tutorials-en\\\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/data-privacy\\\/tutorials-en\\\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-518-web-infrastructure-hardening-control-k.png\",\"datePublished\":\"2026-10-01T07:20:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/data-privacy\\\/tutorials-en\\\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/data-privacy\\\/tutorials-en\\\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/data-privacy\\\/tutorials-en\\\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-518-web-infrastructure-hardening-control-k.png\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-518-web-infrastructure-hardening-control-k.png\",\"width\":1200,\"height\":630,\"caption\":\"Web Infrastructure Hardening: Controlling Third-Party Scripts via Content Security Policy (CSP)\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/data-privacy\\\/tutorials-en\\\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Web Infrastructure Hardening: Controlling Third-Party Scripts via Content Security Policy (CSP)\"}]},{\"@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\":\"Lukas Wojcik\",\"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\":\"Lukas Wojcik\"},\"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":"Web Infrastructure Hardening: Controlling Third-Party Scripts via Content Security Policy (CSP) | Lukas Wojcik","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\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/","og_locale":"en_US","og_type":"article","og_title":"Web Infrastructure Hardening: Controlling Third-Party Scripts via Content Security Policy (CSP) | Lukas Wojcik","og_description":"Technical tutorial on securing WordPress v7.0.2 installations against unauthorized script injections and tracking pixels by enforcing strict Content Security Policy (CSP) headers.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/","og_site_name":"Lukas Wojcik - Blog","article_published_time":"2026-10-01T07:20:00+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-518-web-infrastructure-hardening-control-k.png","type":"image\/png"}],"author":"Lukas Wojcik","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Lukas Wojcik","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/#article","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/"},"author":{"name":"Lukas Wojcik","@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"headline":"Web Infrastructure Hardening: Controlling Third-Party Scripts via Content Security Policy (CSP)","datePublished":"2026-10-01T07:20:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/"},"wordCount":1028,"commentCount":0,"publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-518-web-infrastructure-hardening-control-k.png","keywords":["JavaScript","Tracking","Tutorial","Web Security","WordPress"],"articleSection":["Tutorials"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/","name":"Web Infrastructure Hardening: Controlling Third-Party Scripts via Content Security Policy (CSP) | Lukas Wojcik","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/#primaryimage"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-518-web-infrastructure-hardening-control-k.png","datePublished":"2026-10-01T07:20:00+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/#primaryimage","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-518-web-infrastructure-hardening-control-k.png","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-518-web-infrastructure-hardening-control-k.png","width":1200,"height":630,"caption":"Web Infrastructure Hardening: Controlling Third-Party Scripts via Content Security Policy (CSP)"},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/data-privacy\/tutorials-en\/web-infrastructure-hardening-controlling-third-party-scripts-via-content\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Web Infrastructure Hardening: Controlling Third-Party Scripts via Content Security Policy (CSP)"}]},{"@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":"Lukas Wojcik","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":"Lukas Wojcik"},"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\/posts\/518","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"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=518"}],"version-history":[{"count":4,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/518\/revisions"}],"predecessor-version":[{"id":20957,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/518\/revisions\/20957"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media\/18849"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=518"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/categories?post=518"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=518"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}