romenigld
SecurityError: The operation is insecure. Content Security Policy directive: "default-src 'self'"
I am generated an app with Phoenix 1.6.9 and when I tried to test on the safari browser 15.3 version. But on the brave, firefox, chrome is ok
It’s like the app is loading and re-loading again and again.
I inspect the console and complains for this:
Refused to connect to ws://localhost:4000/live/websocket?_csrf_token=bEogRCU3Vh8iECQ2LTc0OQU1cTRPAARb-8kqNn4ZQDEczXqktbFRbie0&_track_static%5B0%5D=http%3A%2F%2Flocalhost%3A4000%2Fassets%2Fapp.css&_track_static%5B1%5D=http%3A%2F%2Flocalhost%3A4000%2Fassets%2Fapp.js&_mounts=0&vsn=2.0.0 because it appears in neither the connect-src directive nor the default-src directive of the Content Security Policy.
[Error] SecurityError: The operation is insecure.
(função anônima) (app.js:931)
connect (app.js:931)
doConnect (app.js:4370)
connect (app.js:4374)
(função anônima) (app.js:5005)
Código Global (app.js:5007)
And I am trying to have fonts from google fonts by link:
root.html.heex
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">
app.css
body {
font-family: 'Roboto', sans-serif;
--webkit-font-smoothing: antialiased;
color: var(--dark);
}
But it’s not showing the robot font style.
It’s complaining on the brave and firefox browsers this:
localhost/:1 Refused to load the image 'data:image/svg+xml;base64,PHN2ZyBpZD0ic291cmNlIiB3aWR0aD0iMjIiIGhlaWdodD0iMjIiIHZpZXdCb3g9IjAgMCAyMiAyMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iMTEiIGZpbGw9ImJsYWNrIiBmaWxsLW9wYWNpdHk9IjAuOCI+PC9jaXJjbGU+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTUuMDgzNCA0LjU4MzMzSDEzLjMzMzRWNS43NDk5OUgxNS4wODM0QzE1LjcyNjggNS43NDk5OSAxNi4yNSA2LjI3MzI0IDE2LjI1IDYuOTE2NjZWOC42NjY2NkgxNy40MTY3VjYuOTE2NjZDMTcuNDE2NyA1LjYyOTgzIDE2LjM3MDIgN...U4NTIgMTMuOTAyMSAxNC41ODUyIDEzLjM0NzkgMTQuMjQ0IDEzLjAwNjFMMTMuMDcwMyAxMS44MzNDMTMuMjM0MiAxMS40OTA2IDEzLjMzMzQgMTEuMTEyNiAxMy4zMzM0IDEwLjcwODNDMTMuMzMzNCA5LjI2MTA4IDEyLjE1NTYgOC4wODMzMyAxMC43MDg0IDguMDgzMzNDOS4yNjExMiA4LjA4MzMzIDguMDgzMzcgOS4yNjEwOCA4LjA4MzM3IDEwLjcwODNDOC4wODMzNyAxMi4xNTU2IDkuMjYxMTIgMTMuMzMzMyAxMC43MDg0IDEzLjMzMzNDMTEuMTEyNiAxMy4zMzMzIDExLjQ5MDYgMTMuMjM0MiAxMS44MzMgMTMuMDcwMkwxMy4wMDYxIDE0LjI0MzlDMTMuMTc3IDE0LjQxNDggMTMuNDAxIDE0LjUgMTMuNjI1IDE0LjVaIiBmaWxsPSJ3aGl0ZSI+PC9wYXRoPgo8L3N2Zz4=' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.
localhost/:1 Refused to load the stylesheet 'https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'style-src-elem' was not explicitly set, so 'default-src' is used as a fallback.
Refused to load the font 'data:font/truetype;charset=utf-8;base64, d09GRgABAAAAAMjjABIAAAAB2mAAAAAAAADH7AAAAPcAAAHiAAAAAAAAAABHUE9TAACdfAAAIjcAAH80VqR1REdTVUIAAL+0AAAINwAAFD6g7KTPTFRTSAAABwQAAABHAAACQYV/Ri1PUy8yAAACDAAAAFQAAABgZ050kmNtYXAAAB1cAAAChQAAA/wdE0d/Y3Z0IAAAIdQAAAA0AAAANAq+BC1mcGdtAAAf5AAAAQUAAAFzBpmcN2dhc3AAAJ1wAAAADAAAAAwABwAHZ2x5ZgAAJnAAAGxKAADg/GpVnLBoZG14AAAHTAAAFhAAADPIAPyiAmhlYWQAAAGUAAAANQAAADYF/aZQaGhlYQAAAcwAAAAgAAAAJAdxBTBobXR4AAACYAAABKIAAAj0wQRTzWxvY2EAACIIAAAEZwAABHxHMIAQbWF4cAAAAewAAAAgAAAAIARXAs1uYW1lAACSvA...2hawUjGKWSTHlyN3B4j2cWs3I2964qIdNK7Bn7l3NIq2gNwdKsrkImONznSahSZTpEh+owvcW+7Mf+HMCBHCTUSS3UXS/oRb2kl/WKXkVU0IxWdKQr3VmSlVmNtdmIzdiSffjdhinO1apRR/hEi8+3rumZFRzp+eEo1XnM/Kz/ABXXNDcAeAGFUUV3wzAM/it6vowXOA1cj5nxrueojZPWynPUDv58uWO4iT+Q7pBghoLQo1A79g2VrMbK6B75jAN47FBDPU56EMfDZhxDGsfrCrqh3VC5SLURRZY7HQrWYVteKlodpgoio9vOkq8JXPbzETifDPx3LGpP54wWehazx17QCjjf5O3v49DkAG/Yfph1UIbYOhpv69k5oy1XL8G1cpkent9bGPPae7sJ96Ojb5sfFwJm1MFQTnePAla5K8HVgPDWBG5+vRbd2fwJg7xahhNv34+/Lb05R9MPTH3KQBiu2ZYkY43dmoA9tEiqcfHN+Gj2VzMA6Y+oeQ==' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'font-src' was not explicitly set, so 'default-src' is used as a fallback.
I would like a help with this, please!
Marked As Solved
romenigld
I was able to fix installing the fonts locally.
So, I copy and paste the fonts locally on the priv/static/fonts folder:
priv/static/fonts
├── aclonica-v18-latin-regular.woff2
└── lobster-v28-latin-regular.woff2
I put it there because the documentation of the phoenix recommends there like the images as well.
On the app.css I put:
@font-face {
font-family: 'Aclonica';
src: url("/fonts/aclonica-v18-latin-regular.woff2");
}
@font-face {
font-family: "Lobster";
src: url("/fonts/lobster-v28-latin-regular.woff2");
}
So, it is possible to use on the CSS like:
body {
font-family: 'Lobster', 'Aclonica', sans-serif, cursive;
}
To use them with the Tailwind CSS config I put this on the tailwind.config.js:
// See the Tailwind configuration guide for advanced usage
// https://tailwindcss.com/docs/configuration
module.exports = {
content: [
'./js/**/*.js',
'../lib/*_web.ex',
'../lib/*_web/**/*.*ex'
],
theme: {
extend: {
fontFamily: {
'sans': ['Helvetica', 'sans-serif'],
'aclonica': ['Aclonica'],
'lobster': ['Lobster']
},
},
},
plugins: [
require('@tailwindcss/forms')
]
}
So now it is possible to use the fonts in the classes using like this:
- using the Font Aclonica
class="font-aclonica"
or
- using the Font Lobster
class="font-lobster"
And the secret for don’t have any error complaints on the console was the change of the font-src:
I changed to use this "font-src 'self' data:;" on the router.ex file.
So the final code of the router.ex file:
@host :food_order
|> Application.fetch_env!(FoodOrderWeb.Endpoint)
|> Keyword.fetch!(:url)
|> Keyword.fetch!(:host)
@content_security_policy (case Mix.env() do
:prod ->
"default-src 'self';connect-src wss://#{@host};img-src 'self' blob:;"
_ ->
"default-src 'self' 'unsafe-eval' 'unsafe-inline';" <>
"connect-src ws://#{@host}:*;" <>
"img-src 'self' blob: data:;" <>
"font-src 'self' data:;"
end)
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, {FoodOrderWeb.LayoutView, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers, %{"content-security-policy" => @content_security_policy}
end
I was trying to use the import with the google fonts but I was having the errors complaining the font-src duplicate, etc… I don’t know how to fix the usage of the google fonts by URL import.
Is something about the CSP.
The print using the fonts:
Also Liked
evadne
FYI
https://github.com/phoenixframework/phoenix/blob/v1.6.10/lib/phoenix/controller.ex#L1105
ws:// needs to be allowed via CSP (Content Security Policy)
Check plug :put_secure_browser_headers present in relevant pipelines in Phoenix Router, check either default or suitable custom values are used.
Consider Content Security Policy configuration (in Phoenix) | The log of Paul Wilson
Last Post!
BartOtten
This might help you generate a good CSP policy:CSP Generator
There is also an example for Google Fonts.
External Fonts
Using the external (Google) fonts has the benefit the font is probably already cached by a visit to another website using them too. Drawback: The hoster and it’s tracking and also more permissive CSP.
Self hosting
Depending on the use case, you might create a subset of the font and serve that to users to keep the data over the wire to a minimum. No tracking, restrictive CSP, but still a fast initial render with the correct font!
And when you want to go ever further, there is this (upcoming) standard: A New Way To Reduce Font Loading Impact: CSS Font Descriptors — Smashing Magazine
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










