Fork me on GitHub
#yada
<
2020-03-27
>
borkdude12:03:41

we're running into a problem with websockets and Content-Security-Policy when deploying our yada app to a staging environment:

sse.cljs:52 Refused to connect to '' because it violates the following Content Security Policy directive: "default-src https: data: 'unsafe-inline' 'unsafe-eval'". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.
We don't send this header in nginx. Is yada sending a default for this?

borkdude12:03:29

I do see a couple of issues around this: https://github.com/juxt/yada/issues/61

dominicm12:03:36

You can change the CSP per-resource.

borkdude13:03:31

@dominicm I now have this:

(resource
   system
   {:swagger/tags ["app"]
    :id :dre.resources/sse
    :content-security-policy "default-src https: wss: data: 'unsafe-inline' 'unsafe-eval'"
    :methods
    {:get
     {:consumes "application/json"
      :produces "application/json"
      :response
      (fn [ctx]
        (let [req (:request ctx)
              conn (http/websocket-connection req)
              user-id (auth/user-id (user-profile ctx))
              sse (:dre.app.sse/sse system)
              chan (sse/new-chan-for-user! sse user-id)
              _ (-> conn (d/chain
                          (fn [socket]
                            (s/connect chan socket)))
                    (d/catch (fn [e]
                               (error e))))]
          (sse/send-message-to-user sse user-id :sse/ack)
          nil))}}})
but we're still getting something else back in the browser 😕

borkdude13:03:59

something else than: :content-security-policy "default-src https: wss: data: 'unsafe-inline' 'unsafe-eval'"

dominicm13:03:54

I thought it went inside a map

borkdude14:03:45

we used to have it on the top level of our yada resources like months or years ago:

:produces formats
         :consumes formats
         :content-security-policy content-security-policy

borkdude14:03:45

hmm, adding :content-security-policy "default-src https: wss: data: 'unsafe-inline' 'unsafe-eval'" on ALL resources works, but not when I only add it to the resource which produces the websocket:

(defn new-websocket-resource
  [system]
  (resource
   system
   {:swagger/tags ["app"]
    :id :dre.resources/sse
    :content-security-policy "default-src https: wss: data: 'unsafe-inline' 'unsafe-eval'"
    :methods
    {:get
     {:consumes "application/json"
      :produces "application/json"
      :response
      (fn [ctx]
        (let [req (:request ctx)
              conn (http/websocket-connection req)
              user-id (auth/user-id (user-profile ctx))
              sse (:dre.app.sse/sse system)
              chan (sse/new-chan-for-user! sse user-id)
              _ (-> conn (d/chain
                          (fn [socket]
                            (s/connect chan socket)))
                    (d/catch (fn [e]
                               (error e))))]
          (sse/send-message-to-user sse user-id :sse/ack)
          {}))}}}))

borkdude14:03:04

so what's up with that?

dominicm14:03:21

No idea 😹

dominicm14:03:38

Don't you need to adjust the csp elsewhere anyway?

dominicm14:03:54

You need to set the csp for your html pages to allow websockets.

dominicm14:03:01

Not on the websocket resource

borkdude14:03:13

well, then it's fine I guess

borkdude14:03:29

I really don't care as long as this works

dominicm14:03:42

I'm not sure websockets supports headers, it isn't http

borkdude14:03:19

thanks for the help!