{"componentChunkName":"component---src-templates-blog-post-index-js","path":"/o-que-e-e-como-resolver-o-content-security-policy/","result":{"data":{"markdownRemark":{"fields":{"slug":"/o-que-e-e-como-resolver-o-content-security-policy/"},"frontmatter":{"category":"DevOps","date":"10/06/2020","description":"Você conhece a sigla CSP? Veja o que você precisa fazer para deixar sua nota melhor nessas regras de segurança","featuredImage":{"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIDAQX/xAAUAQEAAAAAAAAAAAAAAAAAAAAC/9oADAMBAAIQAxAAAAHrLRULGhX/xAAaEAACAgMAAAAAAAAAAAAAAAAAAQISAxEi/9oACAEBAAEFAskWyDkhGrFOj//EABYRAQEBAAAAAAAAAAAAAAAAABEQIf/aAAgBAwEBPwE1n//EABYRAAMAAAAAAAAAAAAAAAAAABARQf/aAAgBAgEBPwFwf//EABoQAAICAwAAAAAAAAAAAAAAAAEhABARIoH/2gAIAQEABj8CyJsVTKgPK//EABoQAAMBAQEBAAAAAAAAAAAAAAERMQAhQXH/2gAIAQEAAT8hJNnmkH1dFbxeWdTEe5ocLh03/9oADAMBAAIAAwAAABB0H//EABYRAAMAAAAAAAAAAAAAAAAAAAEQMf/aAAgBAwEBPxAyL//EABcRAAMBAAAAAAAAAAAAAAAAAAEQESH/2gAIAQIBAT8QGKX/xAAcEAEBAAICAwAAAAAAAAAAAAABEQAhMWFBcZH/2gAIAQEAAT8QGto8onZlB3kj09uGWTVHnH0QgOvuVCSJ6HJrrAAAAHAZ/9k=","aspectRatio":1.5384615384615385,"src":"/static/1f0fa646762bd060fb2de079a2039422/86e90/csp-traffic.jpg","srcSet":"/static/1f0fa646762bd060fb2de079a2039422/17b1e/csp-traffic.jpg 240w,\n/static/1f0fa646762bd060fb2de079a2039422/2d331/csp-traffic.jpg 480w,\n/static/1f0fa646762bd060fb2de079a2039422/86e90/csp-traffic.jpg 960w","srcWebp":"/static/1f0fa646762bd060fb2de079a2039422/c30ee/csp-traffic.webp","srcSetWebp":"/static/1f0fa646762bd060fb2de079a2039422/e8667/csp-traffic.webp 240w,\n/static/1f0fa646762bd060fb2de079a2039422/87b7f/csp-traffic.webp 480w,\n/static/1f0fa646762bd060fb2de079a2039422/c30ee/csp-traffic.webp 960w","sizes":"(max-width: 960px) 100vw, 960px"}}},"photographer":"","title":"O que é e como resolver o Content Security Policy"},"timeToRead":23,"html":"<p>E ae, meus nobres adoradores de cerveja, código e café. Mais um artigo por aqui no Blog. O primeiro de um assunto que eu tenho tratado na Wooza e tenho curtido bastante, <strong>DevSecOps</strong>. Em si eu nem criei uma categoria somente para ela, aí acabei colocando na categoria DevOps. Falarei aqui sobre o <strong>Content Security Policy</strong>, um cara bem importante e que vejo poucas discussões atualmente.</p>\n<h2>Mas o que seria esse Content Security Policy?</h2>\n<p>Um fodasse sagaz para melhorar a segurança do conteúdo dos sites. Ele evita ataques de Cross Site Scripting (XSS), injeção de dados, bloqueia outros sites de embedarem seus assets, seus arquivos de media, dentre outras diversas coisas.</p>\n<p>Ele ainda não está 100% full power modafoca (nossa, séculos que eu não usava esse termo). Alguns atributos ainda não funcionam corretamente nos browsers.</p>\n<h3>Esse cara é Cross-browser?</h3>\n<p>Em si, não, mas a vantagem é que ele dá merda em browsers antigos, as regras são simplesmente ignoradas.</p>\n<h2>E como implementar essas diretivas?</h2>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 47.3469387755102%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAJABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAECAwX/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAHsvREFh//EABgQAAMBAQAAAAAAAAAAAAAAAAACEQEQ/9oACAEBAAEFAmykFyL3/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGhAAAgIDAAAAAAAAAAAAAAAAAAERICExYf/aAAgBAQAGPwLZhkNz2n//xAAaEAEBAAIDAAAAAAAAAAAAAAABEQBBICEx/9oACAEBAAE/IURCTGh6LvHJLNvXh//aAAwDAQACAAMAAAAQU8//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAdEAEAAQQDAQAAAAAAAAAAAAABEQAQIUExYXGx/9oACAEBAAE/EGY3BEnfpFLPUUBrsrF8z6lnm3//2Q=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image lazyload\"\n        alt=\"Content Security Pollicy\"\n        title=\"Content Security Pollicy\"\n        data-src=\"/static/1fd3722a6bd49193708ed21a5b4a16c6/6a068/content-security-policy.jpg\"\n        data-srcset=\"/static/1fd3722a6bd49193708ed21a5b4a16c6/a0fb2/content-security-policy.jpg 245w,\n/static/1fd3722a6bd49193708ed21a5b4a16c6/6b254/content-security-policy.jpg 490w,\n/static/1fd3722a6bd49193708ed21a5b4a16c6/6a068/content-security-policy.jpg 960w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>É aparentemente simples, mas confesso que não é tanto assim, fora que pode ter algum stress que vou explicar pelo artigo.</p>\n<p>Você precisará de até duas etapas de configuração. A parte do CSP você pode fazer tanto com <a href=\"https://www.brunodulcetti.com/quais-e-como-utilizar-as-meta-tags-na-sua-pagina/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">meta-tags</a>, quanto diretamente no servidor com Headers. Vou mostrar as duas formas. E tem também outras configurações que você precisa setar e que só dá pra fazer com Headers.</p>\n<p>Mas claro, serviços como o <a href=\"https://aws.amazon.com/pt/lambda/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Lambda</a>, da AWS, e o <a href=\"https://www.netlify.com/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Netlify</a> fazem essa configuração ficar ridiculamente fácil de fazer.</p>\n<h2>Mas primeiro vamos ver as notas...</h2>\n<p>Talvez você se pergunte: \"Mas que caralha de nota é essa?\". Relaxa, são notas que seu site recebe dependendo do nível de segurança que ele esteja. Vai de F até A+.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 566px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 88.57142857142857%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAASABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAMBBAX/xAAWAQEBAQAAAAAAAAAAAAAAAAAAAgH/2gAMAwEAAhADEAAAAfQrHstNdLcMaD//xAAaEAABBQEAAAAAAAAAAAAAAAABAAIDERMg/9oACAEBAAEFAhIQ7ZCW1gRPXP8A/8QAFREBAQAAAAAAAAAAAAAAAAAAASD/2gAIAQMBAT8BY//EABcRAQADAAAAAAAAAAAAAAAAAAEAEBH/2gAIAQIBAT8BUml//8QAHhAAAAQHAAAAAAAAAAAAAAAAAAIRMgETIDGRkqH/2gAIAQEABj8CtwNPqGmwJiwSr//EABwQAAICAgMAAAAAAAAAAAAAAAABETFBURCxwf/aAAgBAQABPyGLUneeyJE+kp7aNxmiTEYElrj/2gAMAwEAAgADAAAAEITgAP/EABYRAQEBAAAAAAAAAAAAAAAAAAEgMf/aAAgBAwEBPxABjH//xAAXEQADAQAAAAAAAAAAAAAAAAAAEFFh/9oACAECAQE/EITB/wD/xAAcEAEAAwACAwAAAAAAAAAAAAABABEhMYFhodH/2gAIAQEAAT8QshpVhYO4Tz3vsAULa1JtdZTypVwQK6HmcI6hgDAdQn//2Q=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image lazyload\"\n        alt=\"Nota D+ no Observatory\"\n        title=\"Nota D+ no Observatory\"\n        data-src=\"/static/943ecf69a5ec769042a30246cd956e4f/a0966/primeira-nota.jpg\"\n        data-srcset=\"/static/943ecf69a5ec769042a30246cd956e4f/a0fb2/primeira-nota.jpg 245w,\n/static/943ecf69a5ec769042a30246cd956e4f/6b254/primeira-nota.jpg 490w,\n/static/943ecf69a5ec769042a30246cd956e4f/a0966/primeira-nota.jpg 566w\"\n        sizes=\"(max-width: 566px) 100vw, 566px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>E podemos verificar em dois sites:</p>\n<ul>\n<li><a href=\"https://securityheaders.com/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://securityheaders.com/</a></li>\n<li><a href=\"https://observatory.mozilla.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://observatory.mozilla.org/</a></li>\n</ul>\n<p>Eu só conhecia o Observatory, mas recentemente eu vi esse Security Headers e gostei bastante. O que me deixa um pouco encucado é que um mesmo site pode ter notas diferentes nos sites. Viram ali em cima que minha nota estava tenebrosa antes de au aplicar as policies, né?</p>\n<h3>Lista dos Scores</h3>\n<p>Existe uma pequena lista de coisas que os dois sites verificam, vamos ver abaixo:</p>\n<ul>\n<li><strong>Content Security Policy:</strong> nem preciso falar, é o que estamos debatendo nesse artigo</li>\n<li><strong>Cookies:</strong> verifica o quanto os cookies que seu site gera/possui estão limitados, protegidos de ataques e afins</li>\n<li><strong>Cross-origin Resource Sharing:</strong> lembra do crossdomain, etc? Ele verifica se o conteúdo está acessível de outros domínios</li>\n<li><strong>HTTP Public Key Pinning:</strong> é um cara opcional, que você pode bloquear interceptações de credenciais e dados confidenciais</li>\n<li><strong>HTTP Strict Transport Security:</strong> é um fodasse importante, que avisa os agents do usuário a se conectarem ao site acessado apenas por HTTPS, mesmo se o esquema escolhido for HTTP.</li>\n<li><strong>Redirection:</strong> verifica se está sendo redirecionando o site para https, mesmo que o usuário tente acessar o site diretamente por http</li>\n<li><strong>Referrer Policy:</strong> verifica infos que serão passadas com requisições externas</li>\n<li><strong>Subresource Integrity:</strong> um cara bem útil e simples de se resolver. Você adiciona chaves criptografadas em chamdas de arquivos que veem de uma CDN</li>\n<li><strong>X-Content-Type-Options:</strong> um cara sagaz que diz que não carregará, por exemplo, scripts e estilos que não estejam com o MIME Type definido corretamente</li>\n<li><strong>X-Frame-Options:</strong> com esse cara você faz o controle de quem pode embedar seu conteúdo via iframe</li>\n<li><strong>X-XSS-Protection:</strong> um header que protege de ataques XSS</li>\n</ul>\n<p>Cada um deles possui um peso diferente e reflete de forma diferente na nota. E podemos resolver todos eles em até duas etapas. Vamos fazer esse fodasse?</p>\n<h2>Botando a mão na massa, quer dizer, no código...</h2>\n<p>Primeiro vou mostrar somente a parte dos headers, não mexerei ainda na parte de Content Security Policy. Abaixo temos um código em Node usado no Lambda da AWS. Siga os passos abaixo:</p>\n<ol>\n<li>Entre no <a href=\"https://console.aws.amazon.com/lambda/home?region=us-east-1#/functions\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Console da AWS e ir no Lambda</a>.</li>\n<li>Depois clique no botão <code class=\"language-text\">Create function</code></li>\n<li>Selecione a opção <code class=\"language-text\">Author from scratch</code></li>\n<li>Dê um nome qualquer para sua função</li>\n<li>Selecione <code class=\"language-text\">Node.js 12.x</code> em Runtime</li>\n<li>Cole o código abaixo:</li>\n</ol>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token string\">'use strict'</span><span class=\"token punctuation\">;</span>\nexports<span class=\"token punctuation\">.</span><span class=\"token function-variable function\">handler</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">event<span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">,</span> callback</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// Get contents of response</span>\n  <span class=\"token keyword\">const</span> response <span class=\"token operator\">=</span> event<span class=\"token punctuation\">.</span>Records<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>cf<span class=\"token punctuation\">.</span>response<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> headers <span class=\"token operator\">=</span> response<span class=\"token punctuation\">.</span>headers<span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// Set new headers</span>\n  headers<span class=\"token punctuation\">[</span><span class=\"token string\">'strict-transport-security'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token punctuation\">{</span>\n      key<span class=\"token operator\">:</span> <span class=\"token string\">'Strict-Transport-Security'</span><span class=\"token punctuation\">,</span>\n      value<span class=\"token operator\">:</span> <span class=\"token string\">'max-age=63072000; includeSubdomains; preload'</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n  headers<span class=\"token punctuation\">[</span><span class=\"token string\">'x-content-type-options'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token punctuation\">{</span>\n      key<span class=\"token operator\">:</span> <span class=\"token string\">'X-Content-Type-Options'</span><span class=\"token punctuation\">,</span>\n      value<span class=\"token operator\">:</span> <span class=\"token string\">'nosniff'</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n  headers<span class=\"token punctuation\">[</span><span class=\"token string\">'x-frame-options'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token punctuation\">{</span>\n      key<span class=\"token operator\">:</span> <span class=\"token string\">'X-Frame-Options'</span><span class=\"token punctuation\">,</span>\n      value<span class=\"token operator\">:</span> <span class=\"token string\">'DENY'</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n  headers<span class=\"token punctuation\">[</span><span class=\"token string\">'x-xss-protection'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token punctuation\">{</span>\n      key<span class=\"token operator\">:</span> <span class=\"token string\">'X-XSS-Protection'</span><span class=\"token punctuation\">,</span>\n      value<span class=\"token operator\">:</span> <span class=\"token string\">'1; mode=block'</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n  headers<span class=\"token punctuation\">[</span><span class=\"token string\">'referrer-policy'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token punctuation\">{</span>\n      key<span class=\"token operator\">:</span> <span class=\"token string\">'Referrer-Policy'</span><span class=\"token punctuation\">,</span>\n      value<span class=\"token operator\">:</span> <span class=\"token string\">'same-origin'</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n  headers<span class=\"token punctuation\">[</span><span class=\"token string\">'set-cookie'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token punctuation\">{</span>\n      key<span class=\"token operator\">:</span> <span class=\"token string\">'Set-Cookie'</span><span class=\"token punctuation\">,</span>\n      value<span class=\"token operator\">:</span> <span class=\"token string\">'HttpOnly; Secure; SameSite=Strict'</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">//Return modified response</span>\n  <span class=\"token function\">callback</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">null</span><span class=\"token punctuation\">,</span> response<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 576px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 83.26530612244898%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAARABQDASIAAhEBAxEB/8QAGAABAAMBAAAAAAAAAAAAAAAAAAECAwX/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAAB6Gt71RsJEAf/xAAbEAABBAMAAAAAAAAAAAAAAAACAAEREhMgIv/aAAgBAQABBQKxMWZMcqnWv//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQMBAT8BH//EABgRAAIDAAAAAAAAAAAAAAAAAAEREiAx/9oACAECAQE/AZPRT//EAB4QAAEBCQAAAAAAAAAAAAAAAAACARIgMTIzgZGh/9oACAEBAAY/ApcLa9FKmYHov//EABwQAAICAgMAAAAAAAAAAAAAAAERADEgIXGBsf/aAAgBAQABPyEH90+fsaI4vuQd7BXUAagrD//aAAwDAQACAAMAAAAQi888/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAwEBPxAf/8QAFxEBAAMAAAAAAAAAAAAAAAAAAQAQUf/aAAgBAgEBPxAECmX/AP/EAB0QAAIDAAIDAAAAAAAAAAAAAAERACExIFGhsdH/2gAIAQEAAT8QGzRNgXB9wQ14v2HtMUlH3DOXCmsWwAWBQ2oK4P/Z'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image lazyload\"\n        alt=\"Nota B no Observatory\"\n        title=\"Nota B no Observatory\"\n        data-src=\"/static/ad5fe599e482570dcc8799f661701d24/ac097/nota-b.jpg\"\n        data-srcset=\"/static/ad5fe599e482570dcc8799f661701d24/a0fb2/nota-b.jpg 245w,\n/static/ad5fe599e482570dcc8799f661701d24/6b254/nota-b.jpg 490w,\n/static/ad5fe599e482570dcc8799f661701d24/ac097/nota-b.jpg 576w\"\n        sizes=\"(max-width: 576px) 100vw, 576px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Somente com esses caras aí já conseguimos pular da nota D pra B no Observatory. Uma bela evolução.</p>\n<h3>E no Netlify, #comofas?</h3>\n<p>Veja abaixo como fazer no Netlify:</p>\n<ol>\n<li>Crie um arquivo <code class=\"language-text\">_headers</code> na raiz do seu site. Se for com o Gatsby, coloque na pasta static</li>\n<li>Adicione as seguintes linhas nele:</li>\n</ol>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">/*\n  Strict-Transport-Security: max-age<span class=\"token operator\">=</span><span class=\"token number\">63072000</span><span class=\"token punctuation\">;</span> includeSubdomains<span class=\"token punctuation\">;</span> preload\n  X-Content-Type-Options: nosniff\n  X-Frame-Options: DENY\n  X-XSS-Protection: <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> <span class=\"token assign-left variable\">mode</span><span class=\"token operator\">=</span>block\n  Referrer-Policy: same-origin\n  Set-Cookie: HttpOnly<span class=\"token punctuation\">;</span> Secure<span class=\"token punctuation\">;</span> <span class=\"token assign-left variable\">SameSite</span><span class=\"token operator\">=</span>Strict</code></pre></div>\n<h2>Agora vamos voltar para o Content Security Policy realmente</h2>\n<p>Nesses caras anteriores nós mexemos somente em alguns headers, mas não mexemos no CSP em si. A vantagem é que podemos colocar o CSP via meta-tags. Se você achar dessa forma a mais simples ou não tenha acesso ao Netlify ou Lambda, manda brasa com ele mesmo.</p>\n<p>A tag tem a seguinte estrutura:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">&lt;meta\n  http-equiv=&quot;Content-Security-Policy&quot;\n  content=&quot;SUAS POLICIES VEEM AQUI&quot;\n/&gt;</code></pre></div>\n<p>É uma meta-tag simples, mas só porque está sem o conteúdo ainda. Abaixo vou listar todas as policies que você pode setar:</p>\n<ul>\n<li><strong>base-uri:</strong> aqui você limita o valor que pode ter na tag HTML <code class=\"language-text\">&lt;base&gt;</code></li>\n<li><strong>child-src:</strong> define valores válidos de web workers que são chamados por <code class=\"language-text\">&lt;frame&gt;</code> ou <code class=\"language-text\">&lt;iframe&gt;</code></li>\n<li><strong>connect-src:</strong> esse cara é muito importante e parece um pouco complexo para solucionar, mas depois fica tranquilo. Mais abaixo falarei melhor dele, mal e porcamente falando são suas conexões com serviços, APIs, AJAX, etc</li>\n<li><strong>default-src:</strong> é o cara default que todas as diretivas que possuem o sufixo <code class=\"language-text\">-src</code> recebem caso não tenham setado nada. Quando você o declara, qualquer outra policy receberá o valor atribuído aqui como default</li>\n<li><strong>font-src:</strong> define de onde virão as fontes</li>\n<li><strong>form-action:</strong> define as actions dos seus formulários</li>\n<li><strong>frame-ancestors:</strong> tanto esse quanto o frame-src parecem simples, porém, tem casos onde você precisa tomar cuidados. Explicarei melhor abaixo</li>\n<li><strong>frame-src:</strong> assim como o anterior, precisa de cuidados, mas seria relacionados a integração de iframes na sua página</li>\n<li><strong>img-src:</strong> configura todas as imagens do seu site</li>\n<li><strong>manifest-src:</strong> define o arquivo manifest do seu site</li>\n<li><strong>media-src:</strong> define as medias embedadas do seu site</li>\n<li><strong>navigate-to:</strong> nesse cara você pode limitar por onde o usuário pode navegar, seja por formulários, cliques em links ou chamadas por <code class=\"language-text\">window.location</code>. Caso você use o <code class=\"language-text\">form-action</code> junto com o <code class=\"language-text\">navigate-to</code>, o primeiro será priorizado, descartanto o navigate</li>\n<li><strong>object-src:</strong> raramente você usará esse cara, é para os antigos arquivos de flash</li>\n<li><strong>plugin-types:</strong> você define o MIME type que quer aceitar nas tags <code class=\"language-text\">&lt;object&gt;</code> e <code class=\"language-text\">&lt;embed&gt;</code>, que em si nem são mais utilizadas. E caso você use applets, é só adicionar o valor <code class=\"language-text\">application/x-java-applet</code></li>\n<li><strong>prefetch-src:</strong> é aquela tag <code class=\"language-text\">&lt;link&gt;</code> que faz os prefetchs de arquivos, você define aqui de onde eles podem vir</li>\n<li><strong>report-to:</strong> aqui você passa um grupo de <code class=\"language-text\">Report-To</code> que você adicionou no header HTTP de resposta. Nunca usei, se precisar é só dar uma olhada na <a href=\"https://w3c.github.io/reporting/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">documentação na W3C</a></li>\n<li><strong>sandbox:</strong> similar ao atributo do iframe, você pode liberar, bloquear algumas coisas, como plugins, popups e afins. Esse cara possui diversos valores pra você utilizar, <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox#Syntax\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">veja aqui uma lista deles</a></li>\n<li><strong>script-src:</strong> configura os javascripts que serão acessados pela sua página</li>\n<li><strong>style-src:</strong> define os estilos da sua página</li>\n<li>worker-src: define Workers, SharedWorkers ou service workers válidos</li>\n</ul>\n<p>Existem ainda alguns outras policies, mas como não mostrarei exemplos delas, e nem de algumas que eu listei acima, vou deixar pra lá</p>\n<h3>E como eu coloco esses valores?</h3>\n<p>Simples, coloca tudo separado por ponto e vírgula <code class=\"language-text\">;</code>, mesmo se tiver uma ou mais diretivas. Farei um exemplo abaixo:</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>meta</span> <span class=\"token attr-name\">http-equiv</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Content-Security-Policy<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">content</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>default-src <span class=\"token punctuation\">'</span>self<span class=\"token punctuation\">'</span>; style-src <span class=\"token punctuation\">'</span>self<span class=\"token punctuation\">'</span>;<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span></code></pre></div>\n<p>Confesso que não achei lá muito amigável, mas vou tentar explicar a sequência correta de atribuição de valores:</p>\n<ol>\n<li>policy que você quer adicionar, por exemplo, <code class=\"language-text\">default-src</code>, mas sem estar entre aspas</li>\n<li>depois você coloca o(s) valor(es). Esses valores podem ou não estar entre aspas simples</li>\n</ol>\n<h4>Mas caralha, como assim podem ou não?</h4>\n<p>Simples, existem valores padrões, comuns que podem ser usadas nas policies, esses caras podem ter OU NÃO (sim, realmente confuso) precisar de aspas simples. Explicarei abaixo, relaxa o fodasse ae.</p>\n<h3>Valores comuns para as propriedades no Content Security Policy</h3>\n<p>Abaixo eu vou listar os valores comuns, ou seja, que podem ser usados em todas (ou quase) as policies.</p>\n<ul>\n<li><strong>'self'</strong> - como o nome já diz, serve seu próprio site, só aceitará coisas vindo dele</li>\n<li><strong>'none'</strong> - esse ae bloqueia geral</li>\n<li><strong>blob:</strong> - prestem atenção que esse cara não tem aspas e possui os dois pontos após a palavra. Esse cara serve para liberar blobs (adoro esse termo)</li>\n<li><strong>data:</strong> - se você precisar de algo via Base64, precisará adicionar esse caboclo, e assim como o blob, ele não tem aspas e possui os dois pontos logo após a palavra</li>\n<li><strong>ws:*</strong> - usado para WebSockets, bem importante prestar atenção nesse cara, principalmente em projetos rodando localmente</li>\n<li><strong>gap:</strong> - é um scheme especial do iOS, portanto, pode ser necessário que você utilize, até mesmo no <code class=\"language-text\">default-src</code></li>\n<li><strong>'unsafe-inline'</strong> - esse cara é restrito para algumas policies somente, como a <code class=\"language-text\">style-src</code> e <code class=\"language-text\">script-src</code>. Com esse cara você libera adicão de códigos inline no seu HTML, tanto de estilos, quanto scripts</li>\n<li><strong>'unsafe-eval'</strong> - esse é restrito ao <code class=\"language-text\">script-src</code> e libera o uso do <code class=\"language-text\">eval</code>. Falarei mais sobre ele</li>\n<li><strong>*</strong> - esse cara já dá para se ter uma ideia, serve para liberar a porra toda. Altamente recomendável a não utilização desse caboclo</li>\n</ul>\n<h3>Múltiplos valores</h3>\n<p>E claro que você pode usar múltiplos valores, senão estaríamos fudidos. E fazer isso é bem simples, segue abaixo:</p>\n<div class=\"gatsby-highlight\" data-language=\"erb\"><pre class=\"language-erb\"><code class=\"language-erb\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>meta</span>\n      <span class=\"token attr-name\">http-equiv</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Content-Security-Policy<span class=\"token punctuation\">\"</span></span>\n      <span class=\"token attr-name\">content</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>default-src <span class=\"token punctuation\">'</span>none<span class=\"token punctuation\">'</span>;\n               style-src <span class=\"token punctuation\">'</span>self<span class=\"token punctuation\">'</span> data: outrosite.com;\n               script-src <span class=\"token punctuation\">'</span>self<span class=\"token punctuation\">'</span> blob: data: outrosite.com;<span class=\"token punctuation\">\"</span></span>\n<span class=\"token punctuation\">/></span></span></code></pre></div>\n<p>Quebrei a linha para ficar melhor visualmente, mas pode manter numa linha só também. Percebam que no <code class=\"language-text\">style-src</code> e <code class=\"language-text\">script-src</code> têm mais de um valor nessas policies, separados por espaços e somente o 'self' que possui aspas.</p>\n<p>Vejam também que nesse caso aí eu liberei que estilos e scripts viessem de outro site chamado outrosite.com.</p>\n<h3>E o que acontece se eu não passar os valores corretos?</h3>\n<p>Isso depende. Várias coisas podem acontecer, como por exemplo, um vídeo não abrir, um Google Analytics parar de gravar dados ou até mesmo o site todo parar de funcionar.</p>\n<h2>Mas por que diabos então eu tenho que usar essa bosta?</h2>\n<p>Já ouviram falar da <a href=\"https://www.lgpdbrasil.com.br/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">LGPD</a>? E da <a href=\"https://www.consignet.com.br/lei-geral-protecao-iso-27001/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">ISO 27001</a>? Muitas empresas terão que entrar nesse esquema, seus clientes e afins. Já tem um tempo que os clientes da Wooza estão correndo atrás para ter todas essas proteções, cobranças já estão sendo feitas, etc.</p>\n<p>Mas óbvio que nem tudo é tão simples assim. Não é só colocar o CSP e os Headers que está tudo ok, claro que não. Você precisa avaliar quais estilos, scripts e afins que serão permitidos, abertos.</p>\n<p>Mas o pior disso é o famoso GTM, o Google Tag Manager, que a maioria das pessoas, empresas têm usado.</p>\n<h3>Qual o problema do GTM?</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 57.9591836734694%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAUCAwT/xAAVAQEBAAAAAAAAAAAAAAAAAAACA//aAAwDAQACEAMQAAABb0SwVDoCa//EABgQAQEBAQEAAAAAAAAAAAAAAAEAAgND/9oACAEBAAEFAtrGkbve9//EABcRAAMBAAAAAAAAAAAAAAAAAAEQETH/2gAIAQMBAT8B0xf/xAAWEQEBAQAAAAAAAAAAAAAAAAABECH/2gAIAQIBAT8BDJ//xAAbEAABBAMAAAAAAAAAAAAAAAABAAIQEhEhMf/aAAgBAQAGPwLSrbJHYahH/8QAHRABAAAGAwAAAAAAAAAAAAAAAQAQESExUWFxgf/aAAgBAQABPyElNs8R30CWF1lRgPRKy//aAAwDAQACAAMAAAAQ9C//xAAXEQADAQAAAAAAAAAAAAAAAAABEBFB/9oACAEDAQE/EAK6lX//xAAVEQEBAAAAAAAAAAAAAAAAAAAREP/aAAgBAgEBPxB1P//EABwQAQEAAwADAQAAAAAAAAAAAAERACFBgZGxwf/aAAgBAQABPxCOYARPD33mhEBx8duzDZjQBAhxJfzIqKJFdtS/ck0Z/9k='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image lazyload\"\n        alt=\"Google Tag Manager\"\n        title=\"Google Tag Manager\"\n        data-src=\"/static/235b20fc528e36afc08df7cbd55f5404/8e1fc/google-tag-manager.jpg\"\n        data-srcset=\"/static/235b20fc528e36afc08df7cbd55f5404/a0fb2/google-tag-manager.jpg 245w,\n/static/235b20fc528e36afc08df7cbd55f5404/6b254/google-tag-manager.jpg 490w,\n/static/235b20fc528e36afc08df7cbd55f5404/8e1fc/google-tag-manager.jpg 900w\"\n        sizes=\"(max-width: 900px) 100vw, 900px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Como você adiciona os scripts por lá, eles serão injetados sem nem que você, desenvolvedor, perceba. E imagina o cenário onde o cliente possui um GTM, a sua empresa outro. Sim, isso mesmo, dois GTM's. E imagina que esse seu cliente possui uma agência de publicidade que cuida de toda a parte de mídia, publicidade e afins.</p>\n<p>Olha o quanto que essa relação pode dar merda, pois se a comunicação não estiver ok, quando essa agência subir um fodasse novo lá, não irá funcionar, porque você, desenvolvedor, não adicionou esse cara na whitelist do CSP.</p>\n<h4>Vejamos um exemplo...</h4>\n<p>Pense no seguinte cenário. Você está com uma Landing Page rolando de boa, com seu Content Security Policy na paz, funcionando certinho.</p>\n<p>Agora imagine que seu cliente fará uma campanha fodástica no Jornal Nacional, com isso, essa agência acaba colocando uma nova feature, seja imagem, pixel, vídeo, dentre outros via GTM. E aí essas novas URL's não estão na whitelist dessa Landing Page. O que você acha que acontecerá?</p>\n<p>A campanha não vai funcionar corretamente. E quem que o cliente vai reclamar? Com a agência? Óbvio que não, com a empresa onde você trabalha, claro. E quem vai se fuder nessa? Sim, você mesmo, desenvolvedor ordinário que está lendo esse post neste momento.</p>\n<p>Para a agência tudo estará ok, pois a campanha foi adicionada corretamente via Sales Force, ou afins, pra depois ser adicionada via GTM. Porém, como a sua empresa não foi avisada, essas novas URL's não estarão na whitelist, como já falei trocentas vezes nesse artigo.</p>\n<p>Faço exemplo fugindo do código porque eu tenho certeza que eles acontecerão com a Wooza, empresa onde eu trabalho, e com a empresa de vocês e várias outras.</p>\n<p>E para resolver isso é relativamente simples, mas mexe com comunicação, algo que nunca é simples. Portanto, prepare-se, dará merda.</p>\n<h2>VOLTEMOS AO CÓDIGO, DULCETTI...</h2>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 64.89795918367346%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAUBAgME/8QAFQEBAQAAAAAAAAAAAAAAAAAAAgP/2gAMAwEAAhADEAAAAUs37HJUaBf/xAAcEAACAAcAAAAAAAAAAAAAAAABAgADEBMhIjH/2gAIAQEAAQUC4WuNRXy03UmP/8QAGBEAAwEBAAAAAAAAAAAAAAAAAAERAjH/2gAIAQMBAT8Beo+FP//EABURAQEAAAAAAAAAAAAAAAAAAAAR/9oACAECAQE/AYj/xAAZEAACAwEAAAAAAAAAAAAAAAAAEBEhMTL/2gAIAQEABj8CyS5VnK//xAAaEAADAQEBAQAAAAAAAAAAAAAAAREhUTFx/9oACAEBAAE/IZ5fSDoxHIR8MrSi8KM6VZ//2gAMAwEAAgADAAAAEEg//8QAFhEBAQEAAAAAAAAAAAAAAAAAAQBR/9oACAEDAQE/ENgwsv/EABkRAAEFAAAAAAAAAAAAAAAAAAABESExUf/aAAgBAgEBPxCSWM0//8QAHRABAAICAgMAAAAAAAAAAAAAAQARIUExgVFxof/aAAgBAQABPxAJXvSWeoCxvAoRJpQ+o2QzyxFSsF2+RlaTuf/Z'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image lazyload\"\n        alt=\"Laptop quase fechado simulando segurança\"\n        title=\"Laptop quase fechado simulando segurança\"\n        data-src=\"/static/b8f897b0feecf5c17a00af007b9893ae/6a068/seguranca-computador.jpg\"\n        data-srcset=\"/static/b8f897b0feecf5c17a00af007b9893ae/a0fb2/seguranca-computador.jpg 245w,\n/static/b8f897b0feecf5c17a00af007b9893ae/6b254/seguranca-computador.jpg 490w,\n/static/b8f897b0feecf5c17a00af007b9893ae/6a068/seguranca-computador.jpg 960w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Photo by <a href=\"https://unsplash.com/@fantasyflip?utm_source=unsplash&#x26;utm_medium=referral&#x26;utm_content=creditCopyText\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Philipp Katzenberger</a></p>\n<p>Calma, caralha, não precisa gritar. Vamos ver aqui um lista de possibilidades de valores para as diretivas</p>\n<ul>\n<li><strong>*.codepen.io</strong> - abertura de subdomínios</li>\n<li><strong>api.github.com</strong> - abertura para somente um subdomínio</li>\n<li><strong><a href=\"https://disqus.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://disqus.com</a></strong> - Domínio completo</li>\n</ul>\n<p>Isso é bem simples de entender, certo? Talvez o último que pareça meio que \"Caralha, mas se eu já defini todos os subdomínios, por que preciso dessa URL completa também?\". Concordo, e acho até que poderia ter alguma atualização pra aceitar.</p>\n<p>A explicação é que como o <a href=\"https://disqus.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://disqus.com</a> não está num subdomínio, www por exemplo, ele então não é enxergado pela regra *.disqus.com, portanto, você precisa desse cara também em alguns casos.</p>\n<h2>Boas práticas de Content Security Policy</h2>\n<p>Agora farei uma lista de boas práticas e exemplos de tipos de arquivos que você quiser utilizar. A primeira boa prática é usar valor 'none' para o <code class=\"language-text\">default-src</code>.</p>\n<p>Eu uso? Não, que se foda. Mas claro, por enquanto. O valor 'none' te deixa meio estressado, principalmente para a diretiva <code class=\"language-text\">prefetch-src</code>.</p>\n<h3>Como assim, estressa?</h3>\n<p>Pensa no seguinte cenário, você tem o seu site/blog no Gatsby, Next JS, ou qualquer outro. Por boa prática esses caras vão colocar os arquivos estáticos nos prefetchs. O problema é que com o none esses caras não serão enxergados pelos prefetchs, dando erros no console. Explicarei melhor sobre isso mais abaixo.</p>\n<h3><code class=\"language-text\">frame-src</code> e <code class=\"language-text\">frame-ancestors</code></h3>\n<p>Esse cara pode ser meio chato de entender às vezes, principalmmente pelo segundo. O primeiro serve para você liberar iframes no seu site que vêm de outros domínios, por exemplo, embedar vídeos do Youtube.</p>\n<p>O segundo é o inverso, caso o seu produto precise ser \"acessado\", embedado via iframe, então você precisa adicionar esse segundo cara. Para um cara como o YouTube, por exemplo, provavelmente precisaria adicionar o *, pois seus ancestrais, nossos blogs por exemplo, poderão usar o embed.</p>\n<p>Esse cara raramente será utilizado e uma boa prática é deixa-lo como <code class=\"language-text\">&#39;none&#39;</code>. Mas preste atenção se o seu produto será usado em outros locais. Por exemplo, na Wooza nós temos várias modais que são abertas pelos sites dos clientes, portanto, para cada modal as URL's desses clientes e parceiros precisam ser adicionadas no <code class=\"language-text\">frame-ancestors</code>.</p>\n<p>Como eu uso o YouTube e o Disqus, precisei colocar esses caras. E certamente usarei o CodePen, talvez o Vimeo e Facebook também. Com isso, eu utilizo da seguinte maneira:</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">frame-ancestors <span class=\"token string\">'self'</span><span class=\"token punctuation\">;</span>\nframe-src <span class=\"token string\">'none'</span> https://disqus.com *.youtube.com* .vimeo.com *.codepen.io* .facebook.com<span class=\"token punctuation\">;</span></code></pre></div>\n<p>Cada vez que você for usando outras ferramentas, precisará atualizar esse cara, beleza? Assim como o <code class=\"language-text\">frame-ancestors</code>. Meu Blog não serve para ser embedado em lugar nenhum, então eu deixo <code class=\"language-text\">&#39;none&#39;</code> mesmo.</p>\n<h3><code class=\"language-text\">base-uri</code>, <code class=\"language-text\">form-action</code>, <code class=\"language-text\">manifest-src</code>, <code class=\"language-text\">media-src</code> e <code class=\"language-text\">object-src</code></h3>\n<p>Resolvi falar desses juntos porque são caras que uso valores defaults, e também porque não uso mais de um valor. Abaixo segue como eu utilizo:</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">base-uri <span class=\"token string\">'self'</span><span class=\"token punctuation\">;</span>\nform-action <span class=\"token string\">'self'</span><span class=\"token punctuation\">;</span>\nmanifest-src <span class=\"token string\">'self'</span><span class=\"token punctuation\">;</span>\nmedia-src <span class=\"token string\">'self'</span><span class=\"token punctuation\">;</span>\nobject-src <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>O <code class=\"language-text\">base-uri</code> e o <code class=\"language-text\">manifest-src</code> eu nem preciso explicar, certo? O <code class=\"language-text\">object-src</code> eu acredito que também não, só deixei bloqueado o carregamento de arquivos falsh e afins.</p>\n<p>O <code class=\"language-text\">form-action</code> que talvez você precise trocar, pois está limitado para somente aceitar actions do mesmo domínio. Caso você use algum serviço externo de formulários, precisará adicionar esse domínio aqui.</p>\n<p>E o <code class=\"language-text\">media-src</code> você pode ter que adicionar outras URL's também, caso use vídeos ou áudios de outros lugares que não sejam por iframes.</p>\n<h3><code class=\"language-text\">font-src</code>, <code class=\"language-text\">img-src</code>, <code class=\"language-text\">script-src</code> e <code class=\"language-text\">style-src</code></h3>\n<p>Esses fodasses são os mais \"simples complicados\". Simples de entender, mas a parte complicada são os múltiplos valores que você precisa colocar e atualizar, dependendo dos casos.</p>\n<p>Abaixo segue como eu coloco no meu blog:</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">font-src <span class=\"token string\">'self'</span> data: *.cloudfront.net<span class=\"token punctuation\">;</span>\nimg-src <span class=\"token string\">'self'</span> data: blob: *.google-analytics.com *.viglink.com *.disqus.com *.disquscdn.com ce.lijit.com *.cloudfront.net *.githubusercontent.com<span class=\"token punctuation\">;</span>\nscript-src <span class=\"token string\">'self'</span> <span class=\"token string\">'unsafe-inline'</span> <span class=\"token string\">'unsafe-eval'</span> blob: *.google-analytics.com *.disqus.com *.disquscdn.com *.cloudfront.net<span class=\"token punctuation\">;</span>\nstyle-src <span class=\"token string\">'self'</span> <span class=\"token string\">'unsafe-inline'</span> blob: *.disquscdn.com<span class=\"token punctuation\">;</span></code></pre></div>\n<p>Vejam que o 'self' está em todos, o que é o básico. Você precisa abrir esses arquivos estáticos a partir do seu domínio, ambiente, etc.</p>\n<p>No <code class=\"language-text\">font-src</code> eu tive que colocar o data: e a URL do cloudfront, abirndo para todos os subdomínios. Não sou tão fã de usar o *., mas em casos como esses é necessário, pois você nunca sabe qual URL que será aberta. Na verdade nem precisaria desse cara, mas para eu conseguir enxergar nos Deploys Previews do Netlify, tive que colocar esse cara.</p>\n<p>No <code class=\"language-text\">img-src</code> temos algo parecido com o de fontes, mas ainda tem o blob: e vários domínios. Preciso desses caras porque imagens são adicionadas dinamicamente via Analytics, Disqus, Github e afins. Esse cara certamente precisará ser atualizado algumas vezes, cada vez que você adicionar uma nova integração.</p>\n<p>Deixei o <code class=\"language-text\">script-src</code> e <code class=\"language-text\">style-src</code> por último porque eles possuem dois caras que são os mais chatos. O <code class=\"language-text\">&#39;unsafe-inline&#39;</code> e o <code class=\"language-text\">&#39;unsafe-eval&#39;</code> são necessários na maioria dos casos. O <code class=\"language-text\">&#39;unsafe-eval&#39;</code> eu só usei por causa do Netlify CMS, ele usa no admin deles. Em alguns casos você precisará deixar esse cara, pois alguns scripts, bibliotecas antigas, usam o eval.</p>\n<p>O <code class=\"language-text\">&#39;unsafe-inline&#39;</code> eu tive que adicionar nos dois porque eu uso o Analytics/GTM, e eles usam código inline. Em si tem forma de você deixar esses códigos num arquivo externo, usando da forma como eles nunca mostram. Mas como o Gatsby usa códigos CSS inline, então eu não vi motivo para remover esses caras.</p>\n<h4>Mas por que não usar esses caras, Dulcetti?</h4>\n<p>A partir do momento que você os utiliza, sua nota cai bastante no Observatory. No Security Headers também fica um warning, mas a nota não fica tão ferrada assim não.</p>\n<p>Caso no seu trabalho você precise estar com nota A no Observatory e você usar o GTM ou Analytics, então estará fudido, pois será impossível. Isso porque ao usar em UMA ÚNICA diretiva, sua nota já cai.</p>\n<p>Bom, mas como eu preciso usar, que se foda, caguei pra nota máxima. E como o Gatsby usa CSS inline, não adianta colocar o Analytics num arquivo externo, pois o <code class=\"language-text\">&#39;unsafe-inline&#39;</code> do <code class=\"language-text\">style-src</code>, por causa do Gatsby, deixará minha nota baixa do mesmo jeito, então caguei.</p>\n<p>Em si você precisa explicar todos esses fodasses para sua empresa, clientes e afins, já elvis?</p>\n<h3><code class=\"language-text\">prefetch-src</code> e o <code class=\"language-text\">connect-src</code></h3>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">prefetch-src <span class=\"token string\">'self'</span> *.netlify.app https://disqus.com *.disqus.com *.disquscdn.com<span class=\"token punctuation\">;</span>\nconnect-src <span class=\"token string\">'self'</span> <span class=\"token string\">'unsafe-inline'</span> data: gap: ws:* ssl.gstatic.com *.cloudfront.net *.disqus.com *.disquscdn.com *.google-analytics.com api.github.com *.algolia.net *.algolianet.com<span class=\"token punctuation\">;</span></code></pre></div>\n<p>Deixei esses dois por último porque são chatinhos de explicar e entender algumas vezes. O <code class=\"language-text\">prefetch-src</code> é mais ou menos parecido como o <code class=\"language-text\">script-src</code> e o <code class=\"language-text\">style-src</code>, serve para os arquivos que você quer pré-carregar. Geralmente usamos os do mesmo domínio, com isso, somente o <code class=\"language-text\">&#39;self&#39;</code> já estaria bom, porém, com os builds de Gatsby e afins, você precisará colocar outros caras, como Disqus, etc. Esse cara tem um ponto chato também que falarei depois.</p>\n<p>Em si o <code class=\"language-text\">prefetch-src</code> tem <a href=\"https://bugs.chromium.org/p/chromium/issues/detail?id=801561\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">alguns bugs de funcionalidade no Chrome</a>, então nem me preocupo tanto assim com ele.</p>\n<p>O <code class=\"language-text\">connect-src</code> é importante, pois será para suas conexões com API's, dentre outros. Você tem que tomar bastante cuidado, pois certamente utilizará API's de serviços externos, tendo que colocar as URL's nesse cara. Veja que coloquei cloudfront, disqus, serviços do google e também o Algolia, que uso como busca.</p>\n<p>Veja também que tem a parte de WebSockets, serve muitas vezes para quando você está testando localmente com Gatsby ou outro framework. Fora o ap, data, etc.</p>\n<h2>Policies que não são permitidas via meta-tag</h2>\n<p>Sim, existem algumas diretivas com essa limitação, portanto, você precisa setar via Header mesmo. Segue abaixo a lista desses caras:</p>\n<ul>\n<li>sandbox</li>\n<li>report-uri</li>\n<li>frame-ancestors</li>\n</ul>\n<h2>Mas como usar o Content Security Policy então? Via Header ou via Meta-tag?</h2>\n<p>Geralmente é recomendado fazer tudo via Header. Mas você pode usar o CSP via meta-tags e os outros como Headers mesmo. Felizmente o Netlify facilita bastante isso. O Lambda em si nem é tão fácil pra fazer isso, mas facilita um pouco de configurar.</p>\n<h2>Bom, e como ficaram os seus Headers CSP, Dulça?</h2>\n<p>Vou mostrar aqui abaixo, tanto no Netlify, quanto no Lambda. E mostrarei também com as <a href=\"https://www.brunodulcetti.com/quais-e-como-utilizar-as-meta-tags-na-sua-pagina/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">meta-tags</a>. Partiu?</p>\n<h3>Adicionando headers de Content Security Policy no Netlify</h3>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">/*\n  Strict-Transport-Security: max-age<span class=\"token operator\">=</span><span class=\"token number\">63072000</span><span class=\"token punctuation\">;</span> includeSubdomains<span class=\"token punctuation\">;</span> preload\n  Content-Security-Policy: default-src <span class=\"token string\">'self'</span> *.disqus.com https://disqus.com *.disquscdn.com *.cloudfront.net<span class=\"token punctuation\">;</span> connect-src <span class=\"token string\">'self'</span> <span class=\"token string\">'unsafe-inline'</span> data: gap: ws:* ssl.gstatic.com *.cloudfront.net *.disqus.com *.disquscdn.com *.google-analytics.com api.github.com *.algolia.net *.algolianet.com<span class=\"token punctuation\">;</span> font-src <span class=\"token string\">'self'</span> data: *.cloudfront.net<span class=\"token punctuation\">;</span> frame-src <span class=\"token string\">'self'</span> https://disqus.com *.youtube.com *.vimeo.com *.codepen.io *.facebook.com<span class=\"token punctuation\">;</span> img-src <span class=\"token string\">'self'</span> data: blob: *.google-analytics.com *.viglink.com *.disqus.com *.disquscdn.com ce.lijit.com *.cloudfront.net *.githubusercontent.com<span class=\"token punctuation\">;</span> object-src <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> prefetch-src <span class=\"token string\">'self'</span> *.netlify.app https://disqus.com *.disqus.com *.disquscdn.com<span class=\"token punctuation\">;</span> script-src <span class=\"token string\">'self'</span> <span class=\"token string\">'unsafe-inline'</span> <span class=\"token string\">'unsafe-eval'</span> blob: *.google-analytics.com *.disqus.com *.disquscdn.com *.cloudfront.net<span class=\"token punctuation\">;</span> style-src <span class=\"token string\">'self'</span> <span class=\"token string\">'unsafe-inline'</span> blob: *.disquscdn.com<span class=\"token punctuation\">;</span>\n  Feature-Policy: accelerometer <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> ambient-light-sensor <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> autoplay <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> camera <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> encrypted-media <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> fullscreen <span class=\"token string\">'self'</span><span class=\"token punctuation\">;</span> geolocation <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> gyroscope <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> magnetometer <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> microphone <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> midi <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> payment <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span>  picture-in-picture <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> speaker <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> sync-xhr <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> usb <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span> vr <span class=\"token string\">'none'</span><span class=\"token punctuation\">;</span>\n  X-Content-Type-Options: nosniff\n  X-Frame-Options: DENY\n  X-XSS-Protection: <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> <span class=\"token assign-left variable\">mode</span><span class=\"token operator\">=</span>block\n  Referrer-Policy: same-origin\n  Set-Cookie: HttpOnly<span class=\"token punctuation\">;</span> Secure<span class=\"token punctuation\">;</span> <span class=\"token assign-left variable\">SameSite</span><span class=\"token operator\">=</span>Strict\n</code></pre></div>\n<h3>Agora vamos ver os Headers no Lambda:</h3>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token string\">'use strict'</span><span class=\"token punctuation\">;</span>\nexports<span class=\"token punctuation\">.</span><span class=\"token function-variable function\">handler</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">event<span class=\"token punctuation\">,</span> context<span class=\"token punctuation\">,</span> callback</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// Pega o conteudo do response</span>\n  <span class=\"token keyword\">const</span> response <span class=\"token operator\">=</span> event<span class=\"token punctuation\">.</span>Records<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>cf<span class=\"token punctuation\">.</span>response<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> headers <span class=\"token operator\">=</span> response<span class=\"token punctuation\">.</span>headers<span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// Seta os novos headers</span>\n  headers<span class=\"token punctuation\">[</span><span class=\"token string\">'strict-transport-security'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span>\n    key<span class=\"token operator\">:</span> <span class=\"token string\">'Strict-Transport-Security'</span><span class=\"token punctuation\">,</span>\n    value<span class=\"token operator\">:</span> <span class=\"token string\">'max-age=63072000; includeSubdomains; preload'</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n  headers<span class=\"token punctuation\">[</span><span class=\"token string\">'content-security-policy'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span>\n    key<span class=\"token operator\">:</span> <span class=\"token string\">'Content-Security-Policy'</span><span class=\"token punctuation\">,</span>\n    value<span class=\"token operator\">:</span> <span class=\"token string\">\"default-src 'self' *.disqus.com https://disqus.com *.disquscdn.com *.cloudfront.net; connect-src 'self' 'unsafe-inline' data: gap: ws:* ssl.gstatic.com *.cloudfront.net *.disqus.com *.disquscdn.com *.google-analytics.com api.github.com *.algolia.net *.algolianet.com; font-src 'self' data: *.cloudfront.net; frame-src 'self' https://disqus.com *.youtube.com *.vimeo.com *.codepen.io *.facebook.com; img-src 'self' data: blob: *.google-analytics.com *.viglink.com *.disqus.com *.disquscdn.com ce.lijit.com *.cloudfront.net *.githubusercontent.com; object-src 'none'; prefetch-src 'self' *.netlify.app https://disqus.com *.disqus.com *.disquscdn.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.google-analytics.com *.disqus.com *.disquscdn.com *.cloudfront.net; style-src 'self' 'unsafe-inline' blob: *.disquscdn.com;\"</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n  headers<span class=\"token punctuation\">[</span><span class=\"token string\">'feature-policy'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span>\n    key<span class=\"token operator\">:</span> <span class=\"token string\">'Feature-Policy'</span><span class=\"token punctuation\">,</span>\n    value<span class=\"token operator\">:</span> <span class=\"token string\">\"accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; camera 'none'; encrypted-media 'none'; fullscreen 'self'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none';  picture-in-picture 'none'; speaker 'none'; sync-xhr 'none'; usb 'none'; vr 'none'\"</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n  headers<span class=\"token punctuation\">[</span><span class=\"token string\">'x-content-type-options'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span>\n    key<span class=\"token operator\">:</span> <span class=\"token string\">'X-Content-Type-Options'</span><span class=\"token punctuation\">,</span>\n    value<span class=\"token operator\">:</span> <span class=\"token string\">'nosniff'</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n  headers<span class=\"token punctuation\">[</span><span class=\"token string\">'x-frame-options'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span>\n    key<span class=\"token operator\">:</span> <span class=\"token string\">'X-Frame-Options'</span><span class=\"token punctuation\">,</span>\n    value<span class=\"token operator\">:</span> <span class=\"token string\">'DENY'</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n  headers<span class=\"token punctuation\">[</span><span class=\"token string\">'x-xss-protection'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span>\n    key<span class=\"token operator\">:</span> <span class=\"token string\">'X-XSS-Protection'</span><span class=\"token punctuation\">,</span>\n    value<span class=\"token operator\">:</span> <span class=\"token string\">'1; mode=block'</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n  headers<span class=\"token punctuation\">[</span><span class=\"token string\">'referrer-policy'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span>\n    key<span class=\"token operator\">:</span> <span class=\"token string\">'Referrer-Policy'</span><span class=\"token punctuation\">,</span>\n    value<span class=\"token operator\">:</span> <span class=\"token string\">'same-origin'</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n  headers<span class=\"token punctuation\">[</span><span class=\"token string\">'set-cookie'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">{</span>\n    key<span class=\"token operator\">:</span> <span class=\"token string\">'Set-Cookie'</span><span class=\"token punctuation\">,</span>\n    value<span class=\"token operator\">:</span> <span class=\"token string\">'HttpOnly; Secure; SameSite=Strict'</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// Retorna o response modificado</span>\n  <span class=\"token function\">callback</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">null</span><span class=\"token punctuation\">,</span> response<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Não esqueçam que além de criar o Lambda, vocês precisam adicionar esse cara no Beahaviors do domínio lá no CloudFront. Adicionem o valor <code class=\"language-text\">index.html</code> como valor no Path Pattern e está tudo certo. Se tiver alguma dúvida é só perguntar nos comentários.</p>\n<p>Perceba também que eu adicionei um cara <code class=\"language-text\">Feature-Policy</code>, ele bloqueia qualquer feature HTML5. Em si ele nem afeta no Observatory, mas afeta no Security Headers. Como eu não uso nada da API do HTML5, coloquei esse cara. Verifique o que você necessita e faça ajustes no seu projeto se precisar.</p>\n<h2>Agora mostra o seu Content Security Policy com meta-tags, Dulcetti</h2>\n<p>Agora mesmo, bora ver aqui abaixo com HTML normal:</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>meta</span>\n  <span class=\"token attr-name\">http-equiv</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Content-Security-Policy<span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">content</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>default-src <span class=\"token punctuation\">'</span>self<span class=\"token punctuation\">'</span> *.disqus.com https://disqus.com *.disquscdn.com *.cloudfront.net;\n    connect-src <span class=\"token punctuation\">'</span>self<span class=\"token punctuation\">'</span> <span class=\"token punctuation\">'</span>unsafe-inline<span class=\"token punctuation\">'</span> data: gap: ws:* ssl.gstatic.com *.cloudfront.net *.disqus.com *.disquscdn.com *.google-analytics.com api.github.com *.algolia.net *.algolianet.com;\n    font-src <span class=\"token punctuation\">'</span>self<span class=\"token punctuation\">'</span> data: *.cloudfront.net;\n    frame-src <span class=\"token punctuation\">'</span>self<span class=\"token punctuation\">'</span> https://disqus.com *.youtube.com *.vimeo.com *.codepen.io *.facebook.com;\n    img-src <span class=\"token punctuation\">'</span>self<span class=\"token punctuation\">'</span> data: blob: *.google-analytics.com *.viglink.com *.disqus.com *.disquscdn.com ce.lijit.com *.cloudfront.net *.githubusercontent.com;\n    object-src <span class=\"token punctuation\">'</span>none<span class=\"token punctuation\">'</span>;\n    prefetch-src <span class=\"token punctuation\">'</span>self<span class=\"token punctuation\">'</span> *.netlify.app https://disqus.com *.disqus.com *.disquscdn.com;\n    script-src <span class=\"token punctuation\">'</span>self<span class=\"token punctuation\">'</span> <span class=\"token punctuation\">'</span>unsafe-inline<span class=\"token punctuation\">'</span> <span class=\"token punctuation\">'</span>unsafe-eval<span class=\"token punctuation\">'</span> blob: *.google-analytics.com *.disqus.com *.disquscdn.com *.cloudfront.net;\n    style-src <span class=\"token punctuation\">'</span>self<span class=\"token punctuation\">'</span> <span class=\"token punctuation\">'</span>unsafe-inline<span class=\"token punctuation\">'</span> blob: *.disquscdn.com;<span class=\"token punctuation\">\"</span></span>\n<span class=\"token punctuation\">/></span></span></code></pre></div>\n<p>E agora com JSX</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>meta</span>\n  <span class=\"token attr-name\">httpEquiv</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Content-Security-Policy<span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">content</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">default-src 'self' *.disqus.com https://disqus.com *.disquscdn.com *.cloudfront.net;\n    connect-src 'self' 'unsafe-inline' data: gap: ws:* ssl.gstatic.com *.cloudfront.net *.disqus.com *.disquscdn.com *.google-analytics.com api.github.com *.algolia.net *.algolianet.com;\n    font-src 'self' data: *.cloudfront.net;\n    frame-src 'self' https://disqus.com *.youtube.com *.vimeo.com *.codepen.io *.facebook.com;\n    img-src 'self' data: blob: *.google-analytics.com *.viglink.com *.disqus.com *.disquscdn.com ce.lijit.com *.cloudfront.net *.githubusercontent.com;\n    object-src 'none';\n    prefetch-src 'self' *.netlify.app https://disqus.com *.disqus.com *.disquscdn.com;\n    script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.google-analytics.com *.disqus.com *.disquscdn.com *.cloudfront.net;\n    style-src 'self' 'unsafe-inline' blob: *.disquscdn.com;\n  </span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">}</span></span>\n<span class=\"token punctuation\">/></span></span></code></pre></div>\n<h2>Agora a cerveja no bolo: Subresource Integrity</h2>\n<p>Esse cara você já deve ter visto em alguns casos, por exemplo na parte de downloads do <a href=\"https://getbootstrap.com/docs/4.5/getting-started/download/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Bootstrap</a>. Veja que na tag ele tem dois atributos:</p>\n<ul>\n<li>integrity</li>\n<li>crossorigin</li>\n</ul>\n<p>Mal e porcamente falando, seria uma integridade do código junto à URL, pra só funcionar mesmo se estiver realmente vindo da origem correta. E o crossorigin é pra liberar que sites terceiros usem o caboclo, pra não dar merda de CORS.</p>\n<p>Para resolver esse cara no Gatsby é <a href=\"https://github.com/ovhemert/gatsby-plugin-sri\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">só instalar esse plugin aqui de SRI</a>. É bem simples de configurar, basta adicionar o código abaixo no arquivo <code class=\"language-text\">gatsby-config.js</code></p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token punctuation\">{</span>\n  resolve<span class=\"token operator\">:</span> <span class=\"token string\">'gatsby-plugin-sri'</span><span class=\"token punctuation\">,</span>\n  options<span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    hash<span class=\"token operator\">:</span> <span class=\"token string\">'sha512'</span><span class=\"token punctuation\">,</span>\n    crossorigin<span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span></code></pre></div>\n<p>Só fique ligado caso esteja usando o Netlify com o recurso <strong>Assets optimization</strong> ligado, pois ele chamará os arquivos vindo da CDN do CloudFront, portanto, outro domínio. Aí acaba quebrando, não funcionando.</p>\n<p>Esse cara ajuda a te dar mais cinco pontos na nota do Observatory e conseguir um B+ na nota.</p>\n<h2>Finalizando</h2>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 578px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 86.93877551020408%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAARABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAMBBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHoVptYsAgD/8QAGhAAAgIDAAAAAAAAAAAAAAAAAQIAEhMgIv/aAAgBAQABBQIMwbK0DkynWv8A/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAwEBPwEf/8QAFxEAAwEAAAAAAAAAAAAAAAAAARIgUf/aAAgBAgEBPwFtEf/EAB0QAAECBwAAAAAAAAAAAAAAAAABAhESIDEyM6H/2gAIAQEABj8Ctw1uMFQmjV//xAAdEAADAAAHAAAAAAAAAAAAAAAAAREgITFBYXHw/9oACAEBAAE/IY+2rpB40K6+Ex53ZIJJ7iwf/9oADAMBAAIAAwAAABDbDzz/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAZEQEAAgMAAAAAAAAAAAAAAAABABARMVH/2gAIAQIBAT8QMtEU5f8A/8QAHRABAAIBBQEAAAAAAAAAAAAAAQARMSAhUXGB8P/aAAgBAQABPxBKAHZBTu4i19vY1RjVJfeYByD4Kig0aM7TDR//2Q=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image lazyload\"\n        alt=\"Nota B+ no Observatory\"\n        title=\"Nota B+ no Observatory\"\n        data-src=\"/static/ba5a01a64430a8910aceb23f85124c61/49151/nota-melhor-observatory.jpg\"\n        data-srcset=\"/static/ba5a01a64430a8910aceb23f85124c61/a0fb2/nota-melhor-observatory.jpg 245w,\n/static/ba5a01a64430a8910aceb23f85124c61/6b254/nota-melhor-observatory.jpg 490w,\n/static/ba5a01a64430a8910aceb23f85124c61/49151/nota-melhor-observatory.jpg 578w\"\n        sizes=\"(max-width: 578px) 100vw, 578px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Bom, tentei resumir aqui pra vocês, mas percebi que não consegui porque o artigo ficou grande pra meireles. Antes eu estava com uma nota D, agora ficou B+.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 980px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 24.081632653061227%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAFABQDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAECBf/EABYBAQEBAAAAAAAAAAAAAAAAAAEAAv/aAAwDAQACEAMQAAAB2JLNwv8A/8QAFxABAQEBAAAAAAAAAAAAAAAAARECEP/aAAgBAQABBQIJkvP/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAZEAABBQAAAAAAAAAAAAAAAAAAARARMUH/2gAIAQEABj8CuVMb/8QAGhAAAQUBAAAAAAAAAAAAAAAAAQAQESExkf/aAAgBAQABPyE1tDSptPDf/9oADAMBAAIAAwAAABCLz//EABYRAQEBAAAAAAAAAAAAAAAAAAEQMf/aAAgBAwEBPxAMn//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABsQAAEEAwAAAAAAAAAAAAAAABEAASExUYHR/9oACAEBAAE/EBYI6K9KXSw/qEMbX//Z'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image lazyload\"\n        alt=\"Nota A no Security Headers\"\n        title=\"Nota A no Security Headers\"\n        data-src=\"/static/b8fd4fd4cfb3edf5665f1a3cabcbfd2c/4012a/nota-a-security-headers.jpg\"\n        data-srcset=\"/static/b8fd4fd4cfb3edf5665f1a3cabcbfd2c/a0fb2/nota-a-security-headers.jpg 245w,\n/static/b8fd4fd4cfb3edf5665f1a3cabcbfd2c/6b254/nota-a-security-headers.jpg 490w,\n/static/b8fd4fd4cfb3edf5665f1a3cabcbfd2c/4012a/nota-a-security-headers.jpg 980w,\n/static/b8fd4fd4cfb3edf5665f1a3cabcbfd2c/4b7fe/nota-a-security-headers.jpg 1220w\"\n        sizes=\"(max-width: 980px) 100vw, 980px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Mas no Security Headers eu consegui o A, então de boa, já estou deveras satisfeito.</p>\n<p>Vimos que é praticamente impossível chegar no A+ quando você utiliza um Gatsby junto com o um Analytics ou GTM. E eu recomendo mesmo olhar sempre os dois caras:</p>\n<ul>\n<li><a href=\"https://securityheaders.com/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://securityheaders.com/</a></li>\n<li><a href=\"https://observatory.mozilla.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://observatory.mozilla.org/</a></li>\n</ul>\n<p>E claro, dando prioridade pro primeiro. Monte sempre um plano de atuação pra esse cara, principalmente se você possuir muitos produtos. Vá em cada Squad e monte um plano para cada URL que precise atuar.</p>\n<p>Sente sempre com os PO's para explicar tudo. Se quiser pode chamar os caras de DevOps, DevSecOps ou Infraestrutura para participar e poder tirar qualquer dúvida.</p>\n<p>Não fique neurótico com o A+. Você precisará colocar o <code class=\"language-text\">default-src &#39;none&#39;</code>, por exemplo, o que pode te ferrar no <code class=\"language-text\">prefetch</code>, mas aí é só escolher certinho e ir atuando aos poucos.</p>\n<h3>JÁ CHEGA, DULÇA</h3>\n<p>Beleza, foi mal. Bom, espero que tenha ficado bem explicado. Tá um pouco cansativo, mas acho que foi importante escrever bastante sobre, tentar o máximo explicado possível.</p>\n<p>Só para vocês terem ideia, eu fiz mais de 10 Pull Requests, deploys só pra esse cara chegar no cenário atual. E olha que ainda não é o ideal, 100%, por isso que eu falei da neurose.</p>\n<p>O Netlify até me avisou que eu tinah chegado nos 75% de consumo de tempo de build. Terei que ficar ligado nos meus PR's :P</p>\n<p>Bom, é isso. O que acharam? Aceito sugestões, críticas e afins ;)</p>\n<p>Beijo na alcatra.</p>\n<h3>Links úteis:</h3>\n<ul>\n<li><a href=\"https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Headers/Content-Security-Policy\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Headers/Content-Security-Policy</a></li>\n<li><a href=\"https://w3c.github.io/webappsec-csp/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://w3c.github.io/webappsec-csp/</a></li>\n<li><a href=\"https://infosec.mozilla.org/guidelines/web_security\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://infosec.mozilla.org/guidelines/web_security</a></li>\n<li><a href=\"https://content-security-policy.com/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://content-security-policy.com/</a></li>\n<li><a href=\"https://developer.mozilla.org/pt-BR/docs/Web/HTTP/CSP\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://developer.mozilla.org/pt-BR/docs/Web/HTTP/CSP</a></li>\n</ul>"}},"pageContext":{"nextPost":{"fields":{"slug":"/como-criar-variaveis-de-ambiente-no-nextjs/"},"frontmatter":{"title":"Como criar variáveis de ambiente no Nextjs"}},"previousPost":{"fields":{"slug":"/como-colocar-um-feed-no-seu-blog-com-o-gatsby/"},"frontmatter":{"title":"Como colocar um feed no seu Blog com o Gatsby"}},"slug":"/o-que-e-e-como-resolver-o-content-security-policy/"}},"staticQueryHashes":["1271460761","2963127411","3623170217","764694655"]}