{"id":880,"date":"2016-02-22T05:12:36","date_gmt":"2016-02-22T13:12:36","guid":{"rendered":"https:\/\/www.cloudinsidr.com\/content\/?p=880"},"modified":"2022-03-21T04:42:39","modified_gmt":"2022-03-21T11:42:39","slug":"secure-your-web-server-against-attacks-via-xsrfcsrfxfs-how-to-design-a-content-security-policy","status":"publish","type":"post","link":"https:\/\/www.cloudinsidr.com\/content\/secure-your-web-server-against-attacks-via-xsrfcsrfxfs-how-to-design-a-content-security-policy\/","title":{"rendered":"Create a Content Security Policy to Protect Your Web Application against XSRF\/CSRF\/XFS, Clickjacking and Other Code Injection Attacks"},"content":{"rendered":"<p>[Updated 2019-03-17] Are you wondering why some JavaScript code from external domains simply won&#8217;t execute on your website? The reason could be as simple as an overly restrictive Content Security Policy (CSP for short). This article explains how you can create a Content Security Policy that&#8217;s both protective and functional. It will help you to secure your web server from some types of cross-site request forgery (XSRF\/CSRF\/XFS), clickjacking and other code injection attacks.<\/p>\n<p><!--more--><\/p>\n<h2>Who needs a Content Security Policy<\/h2>\n<p>Have you seen malicious activity in your web server logs or in your analytics suite? Don&#8217;t panic. By using a Content Security Policy, you can defend your infrastructure against cross-site request scripting and cross-site request forgery.<\/p>\n<p>A Content Security Policy (CSP) is a set of directives for the web server can block any content sources except for those you specifically approve (such as your own CDN or your advertising networks). This can considerably limit the exposure of your web applications to content injection and request forgery attacks. With a CSP in place, you take away one major incentive for your users to deactivate JavaScript and give them one more reason to trust your web application.<\/p>\n<p>If your website is using JavaScript\u2014either externalized or inline\u2014you do need a Content Security Policy.<\/p>\n<p>You as the web administrator, along with your web developers, are responsible for ensuring the safety of visitors who trust the code you deploy. A correctly configured Content Security Policy goes a long way towards that end by telling the browser which scripts you explicitly authorize to run on your domain.<\/p>\n<p>How do you know if your website has a Content Security Policy in place? One way to quickly verify if security headers are set it is by using the free service\u00a0<a href=\"https:\/\/securityheaders.io\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/securityheaders.io\/<\/a>. This service will list any directives you have in place, but it can&#8217;t judge if your Content Security Policy headers make sense. You have to make that decision yourself.<\/p>\n<h2>How a Content Security Policy protects your web application<\/h2>\n<p>A Content Security Policy defines a set of trusted domains. It says that you want your visitors&#8217; web browsers to trust them\u00a0 when executing JavaScript (and usually, distrust anything else).<\/p>\n<h3>The HTTP Content Security Policy header<\/h3>\n<p>A web browser reads the Content Security Policy from the <strong>HTTP\u00a0Content Security Policy header<\/strong> that your web server sends alongside your website content. As of this writing, <a href=\"https:\/\/caniuse.com\/#feat=contentsecuritypolicy\" target=\"_blank\" rel=\"noopener noreferrer\">all reasonably current web browsers support this feature<\/a>. A web browser which supports this feature will block the execution of JavaScript from all sources you do not approve of, thus rendering cross-site request forgery (XSRF\/CSRF\/XFS) attempts totally ineffective (the mechanics of cross-site request forgery are detailed in <a href=\"https:\/\/www.owasp.org\/index.php\/XSS_Filter_Evasion_Cheat_Sheet\" target=\"_blank\" rel=\"noopener noreferrer\">this OWASP document<\/a>).<\/p>\n<p>For example, you may want to embed JavaScript from a web analytics service (such as Google Analytics), a social media widget (Facebook, Twitter, etc.), or an advertising network and disable the execution of code from all other domains, which you haven&#8217;t explicitly approved. All you need to do is whitelist the domains you consider trustworthy in the HTTP\u00a0Content Security Policy header.<\/p>\n<h3>The limitations of CSP<\/h3>\n<p>A Content Security Policy is a whitelist of origin domains of scripts that you consider trustworthy. It is not a firewall. With some additional effort, an attacker might be able to circumvent your CSP. For example like this (see this <a href=\"https:\/\/gist.github.com\/davidgilbertson\/132497d7e0a9a815b150e35d44660893#file-csp-bypass-js\" target=\"_blank\" rel=\"noopener noreferrer\">GitHubGist<\/a> and also <a href=\"https:\/\/hackernoon.com\/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5\" target=\"_blank\" rel=\"noopener noreferrer\">this<\/a> post by David Gilbertson):<\/p>\n<p><script src=\"https:\/\/gist.github.com\/davidgilbertson\/132497d7e0a9a815b150e35d44660893.js\"><\/script><\/p>\n<h3>How to work around inline script injection<\/h3>\n<p>A CSP cannot defend your web application from inline script injection. With inline script injection, the malicious payload is being served from a trusted domain and so the browser will accept it as legitimate. In order to safeguard your visitors from inline script injection, there are a few important actions you need to take (see steps 3 and 4 below).<\/p>\n<h3>Understanding the two modes of operation: permissive versus enforcing<\/h3>\n<p>CSP has two modes of operation designed for debugging and deployment:<\/p>\n<ul>\n<li><strong>Content-Security-Policy-Report-Only<\/strong>: this is the permissive mode; it is not enforcing the current policy but it is reporting violations;<\/li>\n<li><strong>Content-Security-Policy<\/strong>: this is the enforcing mode; your web server is directing each visitor&#8217;s web browser to enforce the policy (the browser will comply providing that it supports the feature and understands the request).<\/li>\n<\/ul>\n<h2>Activate the -Report-Only mode<\/h2>\n<p>It goes without saying that you don&#8217;t have to wreck your website to figure out the policy settings. Begin in the permissive mode. Configure your policy, keeping\u00a0an eye on errors in the Console of Developer Tools panel of your browser. Make sure that you have ironed out all the kinks before you begin enforcing your policy. A half-baked configuration may cause not scripts, images and CSS stylesheets to fail to load correctly.<\/p>\n<p>Only after all errors are gone you will want to switch to the enforcing mode.<\/p>\n<h3>Step 1. Activate the permissive mode<\/h3>\n<p>To activate the permissive mode, open your web server&#8217;s configuration file which defines its behavior for your website in a text editor of your choice. NGINX configuration files are typically located in \/etc\/nginx\/ or its subdirectory sites-enabled.<\/p>\n<p>Enter the following directive on a separate line:<\/p>\n<pre>Content-Security-Policy-Report-Only<\/pre>\n<p>In the permissive mode, reporting is mandatory. If you were to reload the configuration of NGINX and access the website in a web browser, you would see this error in the Console of Developer Tools:<\/p>\n<pre>The Content Security Policy [...] was delivered in report-only mode, but does not specify a 'report-uri'; the policy will have no effect. Please either add a 'report-uri' directive, or deliver the policy via the 'Content-Security-Policy' header.<\/pre>\n<p>Luckily, you can easily fix this nagging\u00a0and be in compliance without writing a line of code thanks to the service <a href=\"https:\/\/report-uri.io\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/report-uri.io\/<\/a>.<\/p>\n<h3>Step 2. Obtain an\u00a0<strong>report-uri endpoint for use with the directive Content-Security-Policy-Report-Only<\/strong><\/h3>\n<p>Here is how to do it in more detail:<em>\u00a0<a href=\"https:\/\/www.cloudinsidr.com\/content\/set-report-uri-prevent-code-injection-attacks\/\">How to set up Report URI to prevent code injection attacks<\/a><\/em>.<\/p>\n<blockquote class=\"wp-embedded-content\" data-secret=\"nLwqUCZ5Mj\"><p><a href=\"https:\/\/www.cloudinsidr.com\/content\/set-report-uri-prevent-code-injection-attacks\/\">How to set up Report URI to prevent code injection attacks<\/a><\/p><\/blockquote>\n<p><iframe class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8220;How to set up Report URI to prevent code injection attacks&#8221; &#8212; Cloud Insidr\" src=\"https:\/\/www.cloudinsidr.com\/content\/set-report-uri-prevent-code-injection-attacks\/embed\/#?secret=3ZUew7Vf7U#?secret=nLwqUCZ5Mj\" data-secret=\"nLwqUCZ5Mj\" width=\"500\" height=\"282\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe><\/p>\n<p>&nbsp;<\/p>\n<h3>Step 3.\u00a0Activate reporting to your new endpoint<\/h3>\n<p>In order to activate reporting to your new endpoint in the permissive mode, add this directive to the NGINX\u00a0server block for your web application:<\/p>\n<pre>add_header Content-Security-Policy-Report-Only \"report-uri https:\/\/addressofyourendpoint.report-uri.com\/r\/d\/csp\/reportOnly\";<\/pre>\n<p>Save the web server configuration file and reload NGINX:<\/p>\n<pre>systemctl reload nginx<\/pre>\n<p>The browser should finally quit nagging\u00a0you about the missing report-uri and the service\u00a0<a href=\"https:\/\/report-uri.com\" target=\"_blank\" rel=\"noopener noreferrer\">report-uri.com<\/a>\u00a0can begin collecting valuable analytics data relevant to the security of your web applications. You can view the results in the section CSP under the subheadings Reports and Graphs.<\/p>\n<p>Right now, your Content Security Policy is empty and not doing anything. It&#8217;s time to whitelist approved content sources.<\/p>\n<h2>How to whitelist approved content sources<\/h2>\n<p>Code injection attacks can be prevented by using the directive script-src. This directive whitelists the content sources that you explicitly approve of. Now the real question is: how do you figure out what to approve of?<\/p>\n<p>Start by setting up the fallback. You are still working in the permissive mode. Changes will take effect immediately, but merely reflect in the reports; they won&#8217;t break your site (unless you break the syntax).<\/p>\n<h3>Step 1. Define the fallback<\/h3>\n<p>Define your fallback (<span style=\"color: #ff0000;\">important! this is a one-liner<\/span>):<\/p>\n<pre>add_header Content-Security-Policy-Report-Only \"default-src 'self'; \r\nreport-uri https:\/\/report-uri.io\/report\/addressofyourendpoint\/reportOnly\";<\/pre>\n<p>You can also be more verbatim by replacing <strong>&#8216;self&#8217;<\/strong> in the\u00a0<strong>default-src<\/strong> directive\u00a0with yourdomainname.tld or even better, include the port number:<\/p>\n<pre>https:\/\/www.yourdomainname.tld:443<\/pre>\n<p>In order for a resource to be loaded, you have to specify it with a directive appropriate for its content type.<\/p>\n<h4>Step 2. Trust yourself with content sources for the protected ressource<\/h4>\n<p>Trust your server\u00a0with all relevant types of content by using appropriate\u00a0directives in this<span style=\"color: #ff0000;\">\u00a0one-liner<\/span>:<\/p>\n<pre>add_header Content-Security-Policy-Report-Only \"default-src 'self';\r\nscript-src 'self';\r\nimg-src 'self';\r\nstyle-src 'self';\r\nfont-src 'self';\r\nform-action 'self';\r\nobject-src 'self'\r\nconnect-src 'self'\";<\/pre>\n<p>(The directive\u00a0obj-src defines the approved location of plug-ins the protected resource may need to load.)<\/p>\n<p>Policy options that are at your disposal include:<\/p>\n<ul>\n<li>&#8216;none&#8217; blocks the use of specified resource,<\/li>\n<li>&#8216;self&#8217; matches the current origin, but not subdomains,<\/li>\n<li>&#8216;unsafe-inline&#8217; allows the use of inline JS and CSS,<\/li>\n<li>&#8216;unsafe-eval&#8217; allows the use of mechanisms like eval().<\/li>\n<\/ul>\n<p>Don&#8217;t add a directive twice, as the second instance of a directive\u00a0will be ignored. Separate additional\u00a0values of a directive by spaces and end the directive with a semicolon (The semicolon after the closing double quotation mark belongs to NGINX).<\/p>\n<h3>Step 3. Decide what to do about inline JavaScript code to prevent script injection attacks<\/h3>\n<p>Now that you have approved your own website, browsers will trust all inline scripts and execute them with reckless abandon. If you don&#8217;t have inline scripts, skip to step 4.<\/p>\n<p>The only way you can safeguard your visitors from inline script injection attacks using CSP requires you to to ban inline scripts as a matter of principle.\u00a0This means that you have to make a few adjustments to the code and markup of your web application:<\/p>\n<ul>\n<li>externalize inline scripts by placing the code contained in script tags in separate files (for example using Adobe Dreamweaver CC)<\/li>\n<li>replace inline event handlers such as\u00a0&lt;a (&#8230;) onclick=&#8221;[JAVASCRIPT]&#8221;&gt; and javascript: URLs with\u00a0addEventListener calls.<\/li>\n<\/ul>\n<h4>Whitelisting individual scripts<\/h4>\n<p>It worth noting that CSP Level 2 allows you to whitelist individual inline scripts by identifying them with a cryptographic nonce (a randomly generated number used once and impossible to guess) or a hash. This is how it looks in the markup:<\/p>\n<pre>&lt;script nonce=analphanumericstringrandomlyregeneratedforeveryrequest&gt;\r\n \/\/ Some inline code I can't remove yet, but need to asap.\r\n&lt;\/script&gt;<\/pre>\n<p>And this is how to declare the above script as legit in the script-src directive:<\/p>\n<pre>Content-Security-Policy: script-src 'nonce-analphanumericstringrandomlyregeneratedforeveryrequest'<\/pre>\n<p>Implementing &#8216;nonce-&#8230;&#8217; is a lot of (rather senseless) work. Unless you are running a site with in an extremely security sensitive context, you may want to use hashes instead.<\/p>\n<p>Navigate to your website in a web browser of your choice and open its <strong>Developer Tools<\/strong>\u00a0panel (right-click on the page, select\u00a0the <strong>Inspect<\/strong> command, then switch to the appropriate view, which is usually\u00a0<strong>Network<\/strong>, and turn your attention to\u00a0the<strong> Console<\/strong>). Make sure your web server has reloaded your most recent configuration file, then reload the page. Look at the output in the browser&#8217;s <strong>Console<\/strong>. Copy the hash value provided by your web browser to your clipboard (including &#8221;) and add it into the script-src directive.<\/p>\n<figure id=\"attachment_907\" aria-describedby=\"caption-attachment-907\" style=\"width: 1024px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Hashes2.png\" rel=\"attachment wp-att-907\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-907\" src=\"https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Hashes2-1024x659.png\" alt=\"Content Policy: copying hashes to allow script execution \" width=\"1024\" height=\"659\" srcset=\"https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Hashes2-1024x659.png 1024w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Hashes2-600x386.png 600w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Hashes2-300x193.png 300w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Hashes2-768x494.png 768w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Hashes2.png 1421w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption id=\"caption-attachment-907\" class=\"wp-caption-text\">Content Policy: copying hashes to allow script execution<\/figcaption><\/figure>\n<p>Using hashes may not be a good idea for inline styles which you don&#8217;t control, however. If your styles are provided by plug-ins, this job would never end and may impede your ability to add content or functionality to the site, because of the sheer amount of work involved in verifying and &#8220;approving&#8221; inline styles for execution. Use the &#8216;unsafe-inline&#8217; directive instead of the hashes, and move on.<\/p>\n<p>WARNING: The parameter\u00a0&#8216;unsafe-inline&#8217; is ignored if either a hash or nonce value is present in the source list for the directive.<\/p>\n<p>Inline CSS (cascading stylesheets) pose a similar challenge, but luckily a far lesser risk\u2014approve them as described in step 4, and move on.<\/p>\n<h3>Step 4. Approve inline CSS<\/h3>\n<p>In order to approve inline CSS, if you were sufficiently paranoid, you would either add a\u00a0hash for each snippet you wished to execute to the <strong>style-src<\/strong>\u00a0directive, or use a \u00a0<strong>&#8216;nonce-&#8230;&#8217;\u00a0<\/strong>evaluation to allow execution (the latter one requires changes to the code). In most cases, this is an overkill and may not be doable if your CMS plugins generate new inline snippets (for example in comments). The easiest way to approve all inline CSS\u00a0involves\u00a0adding\u00a0<strong>&#8216;unsafe-inline&#8217;<\/strong> to your <strong>style-src<\/strong> directive (are you feeling paranoid yet?) like in this <span style=\"color: #ff0000;\">one-liner<\/span>:<\/p>\n<pre>add_header Content-Security-Policy-Report-Only \"default-src 'self';\r\n<span style=\"line-height: 1.5;\">script-src 'self';\r\n<\/span>img-src 'self';\r\nstyle-src 'self' 'unsafe-inline';\r\nfont-src 'self';\r\nform-action 'self';\r\nobject-src 'self'\";<\/pre>\n<p>Now all inline CSS originating from\u00a0your server\u00a0will be executed.<\/p>\n<h4>Step 5. Allow fonts and images with\u00a0data:\u00a0URLs<\/h4>\n<p>Allow fonts and images with <strong>data:<\/strong> URLs by appending\u00a0<strong>data:<\/strong><strong>\u00a0<\/strong>to the\u00a0<strong>img-src<\/strong> and <strong>font-src<\/strong> directives:<\/p>\n<pre>img-src 'self' data:;<\/pre>\n<pre>font-src 'self' data:;<\/pre>\n<h4>Step 6. Allow trusted\u00a0cross-domain <span class=\"caps\">AJAX<\/span> requests and\u00a0begin testing<\/h4>\n<p>Next, you need to trust scripts provided by your analytics services, your advertisers, and the like (if you don&#8217;t feel like trusting external content sources, what&#8217;s the point of loading these files?).<\/p>\n<p>Navigate to your website in a web browser of your choice and open its <strong>Developer Tools<\/strong>\u00a0panel (right-click on the page, select\u00a0the <strong>Inspect<\/strong> command, then switch to the appropriate view, which is usually\u00a0<strong>Network<\/strong>, and turn your attention to\u00a0the<strong> Console<\/strong>).<\/p>\n<p>Make sure your web server has reloaded your most recent configuration file, then reload the page. Look at the output in the browser&#8217;s <strong>Console<\/strong>.<\/p>\n<figure id=\"attachment_889\" aria-describedby=\"caption-attachment-889\" style=\"width: 1024px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/ContentPolicy.png\" rel=\"attachment wp-att-889\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-889\" src=\"https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/ContentPolicy-1024x476.png\" alt=\"Content Policy: verifying errors in the browser Console \" width=\"1024\" height=\"476\" srcset=\"https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/ContentPolicy-1024x476.png 1024w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/ContentPolicy-600x279.png 600w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/ContentPolicy-300x139.png 300w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/ContentPolicy-768x357.png 768w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/ContentPolicy.png 1421w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption id=\"caption-attachment-889\" class=\"wp-caption-text\">Content Policy: verifying errors in the browser Console<\/figcaption><\/figure>\n<p>Now comes the heavy\u00a0lifting: manually evaluating content sources and adding them to the policy is no fun.<\/p>\n<p>For example, the browser may say:<\/p>\n<pre>Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive:\u00a0[...].<\/pre>\n<p>Solution: add\u00a0<strong>&#8216;unsafe-eval&#8217;<\/strong> to the\u00a0Content Security Policy directive\u00a0<strong>script-src<\/strong>.<\/p>\n<p>The browser may complain:<\/p>\n<pre>[Report Only] Refused to execute inline script [...] Either the 'unsafe-inline' keyword, a hash ('sha256-17oBQkrpUDBidsaV61+43f1oWjeWxyMuKwnugVDQFQg='), or a nonce ('nonce-...') is required to enable inline execution.<\/pre>\n<p>That only means you have overlooked an inline script in Step 3 above.<\/p>\n<p>WARNING: It bears repeating that the parameter\u00a0&#8216;unsafe-inline&#8217; will be ignored if either a hash or nonce value is present in the source list for the directive.<\/p>\n<p>Repeat this procedure for each\u00a0web application and its\u00a0admin front-end to ensure that it is working as desired.\u00a0(When in doubt, refer to the <a href=\"http:\/\/content-security-policy.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Content Security Policy Quick Reference Guide<\/a>)<\/p>\n<h3>Step 7. Switch to the enforcing mode<\/h3>\n<p>Once all errors are fixed, switch to the enforcing mode. Below is an example policy. (Please remember: this is a <span style=\"color: #ff0000;\">one-liner<span style=\"color: #000000;\">; you must\u00a0remove all end-of-line characters before restarting NGINX<\/span><\/span>).<\/p>\n<pre>[sociallocker]add_header Content-Security-Policy \"default-src 'none';\r\nscript-src 'self' 'unsafe-inline' 'unsafe-eval'\r\nhttps:\/\/www.google-analytics.com\/\r\nhttps:\/\/load.sumome.com\/\r\nhttps:\/\/sumome-140a.kxcdn.com\/\r\nhttps:\/\/gc.kis.scr.kaspersky-labs.com\/\r\nhttps:\/\/widgets.pinterest.com\r\nhttps:\/\/buttons.reddit.com\r\nhttps:\/\/www.linkedin.com\r\nhttps:\/\/api.facebook.com\r\nhttps:\/\/api.bufferapp.com;\r\nimg-src 'self' data:\r\nhttps:\/\/sumome-140a.kxcdn.com\r\nhttps:\/\/dashboard.zopim.com\r\nhttps:\/\/affiliate.thesslstore.com\r\nhttps:\/\/ws-na.amazon-adsystem.com\r\nhttps:\/\/ir-na.amazon-adsystem.com\r\nhttps:\/\/images-na.ssl-images-amazon.com\r\nhttps:\/\/www.google-analytics.com\r\nhttps:\/\/stats.g.doubleclick.net\r\nhttps:\/\/secure.gravatar.com;\r\nstyle-src 'self' 'unsafe-inline'\r\nhttps:\/\/fonts.googleapis.com\r\nhttps:\/\/sumome-140a.kxcdn.com\/;\r\nfont-src 'self' data:\r\nhttps:\/\/fonts.gstatic.com\/;\r\nform-action 'self';\r\nconnect-src 'self'\r\nhttps:\/\/apis.google.com https:\/\/sumome.com\/ https:\/\/clients6.google.com https:\/\/sumome-140a.kxcdn.com\/;\r\nobject-src 'self';\r\nreport-uri https:\/\/report-uri.io\/report\/yourreportingendpointwhenenforcing\";[\/sociallocker]<\/pre>\n<h4>Step 8.\u00a0Confirm that your setup is correct and complete<\/h4>\n<p>You can test your policy using these services:<\/p>\n<p><a href=\"https:\/\/report-uri.io\/home\/analyse\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/report-uri.io\/home\/analyse<\/a><\/p>\n<p><a href=\"https:\/\/securityheaders.io\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/securityheaders.io\/<\/a><\/p>\n<p>Also, visit your analytics dashboard to investigate policy violations.<\/p>\n<figure id=\"attachment_911\" aria-describedby=\"caption-attachment-911\" style=\"width: 1024px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Graphs.png\" rel=\"attachment wp-att-911\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-911\" src=\"https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Graphs-1024x641.png\" alt=\"Investigating content security policy violations\" width=\"1024\" height=\"641\" srcset=\"https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Graphs-1024x641.png 1024w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Graphs-600x375.png 600w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Graphs-300x188.png 300w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Graphs-768x481.png 768w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Graphs.png 1205w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption id=\"caption-attachment-911\" class=\"wp-caption-text\">Investigating content security policy violations<\/figcaption><\/figure>\n<p>Speaking of CSP, these are the settings used by Twitter (it&#8217;s a one-liner); they may inspire you to simplify your setup:<\/p>\n<p class=\" language-undefined\"><code class=\" language-undefined\">default-src https:;<br \/>\nconnect-src https:;<br \/>\nfont-src https: data:;<br \/>\nframe-src https: twitter:;<br \/>\nframe-ancestors https:;<br \/>\nimg-src https: data:;<br \/>\nmedia-src https:;<br \/>\nobject-src https:;<br \/>\nscript-src 'unsafe-inline' 'unsafe-eval' https:;<br \/>\nstyle-src 'unsafe-inline' https:;<br \/>\nreport-uri https:\/\/twitter.com\/i\/csp_report?a=NVQWGYLXFVZXO2LGOQ%3D%3D%3D%3D%3D%3D&amp;ro=false;<\/code><\/p>\n<p>One last thing: make sure you back up your web server&#8217;s configuration file.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>[Updated 2019-03-17] Are you wondering why some JavaScript code from external domains simply won&#8217;t execute on your website? The reason could be as simple as an overly restrictive Content Security Policy (CSP for short). This article explains how you can create a Content Security Policy that&#8217;s both protective and functional. It will help you to [&hellip;]<\/p>\n","protected":false},"author":101012,"featured_media":911,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","footnotes":""},"categories":[16,17,33,111,1,6],"tags":[119,188,140,85,7],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Create a Content Security Policy to Protect Your Web Application against XSRF\/CSRF\/XFS, Clickjacking and Other Code Injection Attacks - CloudInsidr<\/title>\n<meta name=\"robots\" content=\"index, follow\" \/>\n<meta name=\"googlebot\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<meta name=\"bingbot\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.cloudinsidr.com\/content\/secure-your-web-server-against-attacks-via-xsrfcsrfxfs-how-to-design-a-content-security-policy\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Create a Content Security Policy to Protect Your Web Application against XSRF\/CSRF\/XFS, Clickjacking and Other Code Injection Attacks - CloudInsidr\" \/>\n<meta property=\"og:description\" content=\"[Updated 2019-03-17] Are you wondering why some JavaScript code from external domains simply won&#8217;t execute on your website? The reason could be as simple as an overly restrictive Content Security Policy (CSP for short). This article explains how you can create a Content Security Policy that&#8217;s both protective and functional. It will help you to [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.cloudinsidr.com\/content\/secure-your-web-server-against-attacks-via-xsrfcsrfxfs-how-to-design-a-content-security-policy\/\" \/>\n<meta property=\"og:site_name\" content=\"CloudInsidr\" \/>\n<meta property=\"article:published_time\" content=\"2016-02-22T13:12:36+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-03-21T11:42:39+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Graphs.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1205\" \/>\n\t<meta property=\"og:image:height\" content=\"754\" \/>\n<meta name=\"twitter:card\" content=\"summary\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/#website\",\"url\":\"https:\/\/www.cloudinsidr.com\/content\/\",\"name\":\"CloudInsidr\",\"description\":\"Cyber security, infotech\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/www.cloudinsidr.com\/content\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/secure-your-web-server-against-attacks-via-xsrfcsrfxfs-how-to-design-a-content-security-policy\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2016\/02\/Graphs.png\",\"width\":1205,\"height\":754,\"caption\":\"Investigating content security policy violations\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/secure-your-web-server-against-attacks-via-xsrfcsrfxfs-how-to-design-a-content-security-policy\/#webpage\",\"url\":\"https:\/\/www.cloudinsidr.com\/content\/secure-your-web-server-against-attacks-via-xsrfcsrfxfs-how-to-design-a-content-security-policy\/\",\"name\":\"Create a Content Security Policy to Protect Your Web Application against XSRF\/CSRF\/XFS, Clickjacking and Other Code Injection Attacks - CloudInsidr\",\"isPartOf\":{\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/secure-your-web-server-against-attacks-via-xsrfcsrfxfs-how-to-design-a-content-security-policy\/#primaryimage\"},\"datePublished\":\"2016-02-22T13:12:36+00:00\",\"dateModified\":\"2022-03-21T11:42:39+00:00\",\"author\":{\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/#\/schema\/person\/73723b2da71b6d515d17ca593ea5dc68\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.cloudinsidr.com\/content\/secure-your-web-server-against-attacks-via-xsrfcsrfxfs-how-to-design-a-content-security-policy\/\"]}]},{\"@type\":[\"Person\"],\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/#\/schema\/person\/73723b2da71b6d515d17ca593ea5dc68\",\"name\":\"Filipe Martins\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/dbac033b4d26da8ca1fbde233e49c8dc?s=96&d=mm&r=g\",\"caption\":\"Filipe Martins\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/posts\/880"}],"collection":[{"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/users\/101012"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/comments?post=880"}],"version-history":[{"count":61,"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/posts\/880\/revisions"}],"predecessor-version":[{"id":2819,"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/posts\/880\/revisions\/2819"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/media\/911"}],"wp:attachment":[{"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/media?parent=880"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/categories?post=880"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/tags?post=880"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}