{"id":1362,"date":"2016-02-24T17:44:00","date_gmt":"2016-02-24T22:44:00","guid":{"rendered":"http:\/\/osric.com\/chris\/accidental-developer\/?p=1362"},"modified":"2016-02-24T17:50:55","modified_gmt":"2016-02-24T22:50:55","slug":"per-directory-x-frame-options-header-apache","status":"publish","type":"post","link":"https:\/\/osric.com\/chris\/accidental-developer\/2016\/02\/per-directory-x-frame-options-header-apache\/","title":{"rendered":"Applying per directory X-Frame-Options headers in Apache"},"content":{"rendered":"<p>To help prevent against click-jacking, I had applied the following to my Apache 2.2 configuration based on the suggestions described in OWASP&#8217;s <a href=\"https:\/\/www.owasp.org\/index.php\/Clickjacking_Defense_Cheat_Sheet\">Clickjacking Defense Cheat Sheet<\/a> and Mozilla Developer Network&#8217;s <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/X-Frame-Options\">The X-Frame-Options response header<\/a>:<\/p>\n<p><code>Header always append X-Frame-Options SAMEORIGIN<\/code><\/p>\n<p>However, my site has certain pages that are included in an iframe on another site, for the purpose of displaying content on digital signage devices. After I added that header, those pages would no longer load in an iframe on the digital signage devices&#8217; browsers.<\/p>\n<p>I thought I might be able to change SAMEORIGIN to ALLOW-FROM and list both the URI of my site and the URI of the digital signage page. However, the <a href=\"https:\/\/tools.ietf.org\/html\/rfc7034\">HTTP Header Field X-Frame-Options RFC<\/a> indicates:<\/p>\n<blockquote><p>Wildcards or lists to declare multiple domains in one ALLOW-FROM statement are not permitted<\/p><\/blockquote>\n<p>The pages I wanted to exempt from the X-Frame-Options restriction exist in their own directory, \/digitalsignage, so I tried to override the X-Frame-Options header in a .htaccess file:<\/p>\n<p><code>Header always append X-Frame-Options ALLOW-ACCESS http:\/\/example.com<\/code><\/p>\n<p>That caused a 500 Server Error. This message appeared in the error logs:<\/p>\n<p><code>.htaccess: error: envclause should be in the form env=envar<\/code><\/p>\n<p>The Header directive must be malformed, but I&#8217;m am not sure how. I did not determine how to properly format the statement so as not to produce that error, although several sites have pointed out that some browsers (Chrome, Safari) do not support ALLOW-ACCESS.<\/p>\n<p>I changed the .htaccess file back to SAMEORIGIN, to match what was in the main site configuration:<\/p>\n<p><code>Header always append X-Frame-Options SAMEORIGIN<\/code><\/p>\n<p>I then noted that the response header sent by the server included SAMEORIGIN twice:<\/p>\n<p><code>Header: SAMEORIGIN, SAMEORIGIN<\/code><\/p>\n<p>That&#8217;s the expected behavior when using <em>append<\/em>. It appeared only once after I changed <em>append<\/em> to <em>set<\/em>:<br \/>\n<code>Header always set X-Frame-Options SAMEORIGIN<\/code><\/p>\n<p>I tried using <em>set<\/em> instead of <em>append<\/em> with ALLOW-ACCESS:<\/p>\n<p><code>Header always set X-Frame-Options ALLOW-ACCESS http:\/\/example.com<\/code><\/p>\n<p>But it still produced the same 500 Server Error.<\/p>\n<p>After reading the documentation for <a href=\"http:\/\/httpd.apache.org\/docs\/2.2\/mod\/mod_headers.html\">Apache&#8217;s mod_headers<\/a>, I realized that <em>unset<\/em> would allow me to remove the X-Frame-Options header from the \/digitalsignage directory:<br \/>\n<code>Header always unset X-Frame-Options<\/code><\/p>\n<p>That worked, and the pages were successfully included as iframes in a page on the digital signage company&#8217;s site.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Applying the following directive in Apache will prevent pages from being embedded in other sites as frames\/iframes:<br \/>\nHeader always append X-Frame-Options SAMEORIGIN<\/p>\n<p>But what if you want to allow some pages to be embedded as frames\/iframes? I was able to do this by unsetting the directive in a .htaccess file.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[73,389,387,384,388,385,386],"class_list":["post-1362","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-apache","tag-clickjacking","tag-frames","tag-headers","tag-iframes","tag-mod_headers","tag-x-frame-options"],"_links":{"self":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts\/1362","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/comments?post=1362"}],"version-history":[{"count":8,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts\/1362\/revisions"}],"predecessor-version":[{"id":1373,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts\/1362\/revisions\/1373"}],"wp:attachment":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/media?parent=1362"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/categories?post=1362"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/tags?post=1362"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}