yada

borkdude 2020-03-27T12:16:41.012Z

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 '<wss://searchdev.doctorevidence.com/api/sse/ws>' 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?

borkdude 2020-03-27T12:17:29.012800Z

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

dominicm 2020-03-27T12:17:30.013Z

Yes.

dominicm 2020-03-27T12:17:36.013500Z

You can change the CSP per-resource.

borkdude 2020-03-27T12:21:58.013900Z

alright!

borkdude 2020-03-27T13:38:31.014400Z

@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)
              _ (-&gt; 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 😕

borkdude 2020-03-27T13:38:59.014600Z

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

dominicm 2020-03-27T13:50:54.014900Z

I thought it went inside a map

dominicm 2020-03-27T13:51:44.015200Z

https://juxt.pro/yada/manual/index.html#cross-origin-resource-sharing-cors access control

borkdude 2020-03-27T14:00:13.015600Z

a map?

borkdude 2020-03-27T14:00:45.016200Z

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

borkdude 2020-03-27T14:04:47.016500Z

that seems to be the correct place: https://github.com/juxt/yada/blob/e92f35d1be6b8fabee65e280efebf71fae9c9b1b/src/yada/schema.clj#L518

dominicm 2020-03-27T14:08:05.017Z

Hmm. Yes.

borkdude 2020-03-27T14:43:45.018Z

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)
              _ (-&gt; 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)
          {}))}}}))

borkdude 2020-03-27T14:51:04.018200Z

so what's up with that?

dominicm 2020-03-27T14:54:21.018600Z

No idea 😹

dominicm 2020-03-27T14:54:38.019200Z

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

dominicm 2020-03-27T14:54:54.019800Z

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

dominicm 2020-03-27T14:55:01.020100Z

Not on the websocket resource

borkdude 2020-03-27T14:55:05.020300Z

oh I see

borkdude 2020-03-27T14:55:13.020500Z

well, then it's fine I guess

dominicm 2020-03-27T14:55:25.020800Z

Yeah.

borkdude 2020-03-27T14:55:29.021Z

I really don't care as long as this works

dominicm 2020-03-27T14:55:42.021500Z

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

borkdude 2020-03-27T14:56:19.021700Z

thanks for the help!