Cloudron makes it easy to run web apps like WordPress, Nextcloud, GitLab on your server. Find out more or install now.


Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Bookmarks
  • Search
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo

Cloudron Forum

Apps | Demo | Docs | Install
  1. Cloudron Forum
  2. Metabase
  3. Metabase CORS and CSP headers

Metabase CORS and CSP headers

Scheduled Pinned Locked Moved Solved Metabase
20 Posts 2 Posters 3.4k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S Offline
      S Offline
      staypath
      wrote on last edited by
      #1

      I'm embedding a Metabase dashboard in an external app via iframe on another domain. The embed is failing to load due to missing Access-control-allow-origin header from Metabase hosted on Cloudron. Is there any way to add this to the nginx config for Metabase? I tried adding custom CSP in the Cloudron app security settings, but it didn't help.

      CleanShot 2024-03-26 at 11.22.18@2x.png

      Thanks!

      1 Reply Last reply
      1
      • S Offline
        S Offline
        staypath
        wrote on last edited by
        #2

        I see this in the nginx config for Metabase on my Cloudron server. Is this effectively disabling any CORS headers that are sent by Metabase itself? If so, that is the problem:

        proxy_hide_header Content-Security-Policy;
        proxy_hide_header X-Frame-Options;

        S 1 Reply Last reply
        0
        • S staypath

          I see this in the nginx config for Metabase on my Cloudron server. Is this effectively disabling any CORS headers that are sent by Metabase itself? If so, that is the problem:

          proxy_hide_header Content-Security-Policy;
          proxy_hide_header X-Frame-Options;

          S Offline
          S Offline
          staypath
          wrote on last edited by staypath
          #3

          @staypath I manually added the CORS headers to Metabase's nginx config:

             add_header 'Access-Control-Allow-Origin' '*' always;
             add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
             add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range, x-metabase-embedded' always;
             add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
          
             # Preflighted requests
             if ($request_method = 'OPTIONS') {
                 add_header 'Access-Control-Allow-Origin' '*';
                 add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                 add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range, x-metabase-embedded';
                 add_header 'Access-Control-Max-Age' 1728000;
                 add_header 'Content-Type' 'text/plain; charset=utf-8';
                 add_header 'Content-Length' 0;
                 return 204;
             }
          

          This fixed the issue. Question: will my nginx changes remain or will they be wiped out upon any changes to the Metabase app?

          girishG 1 Reply Last reply
          0
          • S staypath

            @staypath I manually added the CORS headers to Metabase's nginx config:

               add_header 'Access-Control-Allow-Origin' '*' always;
               add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
               add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range, x-metabase-embedded' always;
               add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
            
               # Preflighted requests
               if ($request_method = 'OPTIONS') {
                   add_header 'Access-Control-Allow-Origin' '*';
                   add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                   add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range, x-metabase-embedded';
                   add_header 'Access-Control-Max-Age' 1728000;
                   add_header 'Content-Type' 'text/plain; charset=utf-8';
                   add_header 'Content-Length' 0;
                   return 204;
               }
            

            This fixed the issue. Question: will my nginx changes remain or will they be wiped out upon any changes to the Metabase app?

            girishG Offline
            girishG Offline
            girish
            Staff
            wrote on last edited by
            #4

            @staypath said in Metabase CORS and CSP headers:

            This fixed the issue. Question: will my nginx changes remain or will they be wiped out upon any changes to the Metabase app?

            It will get wiped out.

            For CORS, the support has to come from the app. Usually, the app serves up CORS headers if it thinks it is "safe". Does metabase not support serving up CORS headers itself without tinkering with the reverse proxy configs ?

            Adjusting reverse proxy configs will obviously work but is not the correct place to have these headers version controlled.

            S 1 Reply Last reply
            0
            • girishG Offline
              girishG Offline
              girish
              Staff
              wrote on last edited by
              #5

              Also, note that embedding does not require CORS. You only need CORS if your UI from another domain is sending a API request to Metabase. If this is the case, be careful that this might be security issue in the first place. Ideally, the backend should make the API call to metabase.

              1 Reply Last reply
              0
              • girishG girish

                @staypath said in Metabase CORS and CSP headers:

                This fixed the issue. Question: will my nginx changes remain or will they be wiped out upon any changes to the Metabase app?

                It will get wiped out.

                For CORS, the support has to come from the app. Usually, the app serves up CORS headers if it thinks it is "safe". Does metabase not support serving up CORS headers itself without tinkering with the reverse proxy configs ?

                Adjusting reverse proxy configs will obviously work but is not the correct place to have these headers version controlled.

                S Offline
                S Offline
                staypath
                wrote on last edited by
                #6

                @girish From what I've read, it seems the Metabase position is "use whatever reverse proxy you have in front of Metabase to add CORS as required". Metabase does seem to insert CSP headers for their embedded dashboards.

                A mitigating factor here is that I'm embedding the Metabase dashboard into an iFrame component in Retool, which I'm sure is complicating things a bit:

                https://retool.com/components/iframe

                However, the ability to modify CORS in nginx the same way you allow us to modify CSP would be useful.

                Thanks

                1 Reply Last reply
                0
                • girishG Offline
                  girishG Offline
                  girish
                  Staff
                  wrote on last edited by
                  #7

                  @staypath Per the code at https://github.com/metabase/metabase/blob/036de06748d6460b8f9d9f2103d50e02c9df9e52/src/metabase/server/middleware/security.clj#L131 , we can tweak embedding-app-origin for CORS . But I think it's only in the metabase pro as per https://www.metabase.com/docs/latest/embedding/interactive-embedding#enabling-interactive-embedding-in-metabase

                  BTW, there is some embedding setting in /admin/settings/embedding-in-other-applications :

                  image.png

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    staypath
                    wrote on last edited by
                    #8

                    Thank you for looking into it. You are correct, the MB_EMBEDDING_APP_ORIGIN env variable is for users doing interactive embedding of Metabase, which is a Pro/Enterprise features and not what we are doing. We are doing public sharing, which is a simple iFrame.

                    Here are the response headers - Metabase doesn't include CORS. CleanShot 2024-03-28 at 14.45.01@2x.png

                    I do not think this is a problem in Cloudron, I was only asking if there is a way to allow Cloudron users to override or provide CORS headers in nginx without having to manually override the nginx config.

                    Thank you

                    girishG 1 Reply Last reply
                    1
                    • S staypath

                      Thank you for looking into it. You are correct, the MB_EMBEDDING_APP_ORIGIN env variable is for users doing interactive embedding of Metabase, which is a Pro/Enterprise features and not what we are doing. We are doing public sharing, which is a simple iFrame.

                      Here are the response headers - Metabase doesn't include CORS. CleanShot 2024-03-28 at 14.45.01@2x.png

                      I do not think this is a problem in Cloudron, I was only asking if there is a way to allow Cloudron users to override or provide CORS headers in nginx without having to manually override the nginx config.

                      Thank you

                      girishG Offline
                      girishG Offline
                      girish
                      Staff
                      wrote on last edited by
                      #9

                      @staypath currently, there is no way to edit CORS headers at the reverse proxy. What you did (to edit the files directly) is the correct approach. But as you found out, app updates will remove that config.

                      I think for Cloudron itself, we won't add a way to edit CORS via the UI. Usually, this is provided by the app and should be provided by the app. Users and packagers should really not be editing CORS configuration directly because only the app author knows the security implications.

                      But with my Cloudron user hat on, I understand that sometimes we are put in these positions where one is forced to hack around things 😕 Maybe we can include user.conf optionally in app nginx configs?

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        staypath
                        wrote on last edited by
                        #10

                        If adding user.conf customization would persist settings like headers in nginx, that might be a good feature. Thanks again.

                        girishG 1 Reply Last reply
                        0
                        • S staypath

                          If adding user.conf customization would persist settings like headers in nginx, that might be a good feature. Thanks again.

                          girishG Offline
                          girishG Offline
                          girish
                          Staff
                          wrote on last edited by girish
                          #11

                          @staypath was discussing this internally and we got a bit confused by your earlier comment in #3 . Do you know how/why adding CORS fixed your embedding issue.

                          Isn't embedding mattermost metabase about adding an IFRAME? If so, this only involves fixing the CSP header and the CORS headers should have no relevance. Did we misunderstand something ? CORS is only applicable if a website frontend, which is not mattermost metabase, is making API calls to mattermost metabase.

                          1 Reply Last reply
                          0
                          • S Offline
                            S Offline
                            staypath
                            wrote on last edited by
                            #12

                            Thanks for the reply. We are embedding Metabase, not Mattermost. I agree with you, normally CORS would not apply, but as I mentioned previously, we are embedding Metabase within a Retool iFrame component. Something about how Retool fetches the iFrame content is making it appear to the browser that it should check for CORS headers. Since CORS headers don't exist, the browser refuses to load the iFrame. I think there are two questions here:

                            1. is CORS even required in this scenario? Maybe it shouldn't be by design, but the Retool iFrame component will not load the Metabase content without CORS headers in place
                            2. in edge cases like this, would the ability to customize nginx headers in Cloudron user.conf solve the issue?

                            Thanks

                            girishG 1 Reply Last reply
                            0
                            • S staypath

                              Thanks for the reply. We are embedding Metabase, not Mattermost. I agree with you, normally CORS would not apply, but as I mentioned previously, we are embedding Metabase within a Retool iFrame component. Something about how Retool fetches the iFrame content is making it appear to the browser that it should check for CORS headers. Since CORS headers don't exist, the browser refuses to load the iFrame. I think there are two questions here:

                              1. is CORS even required in this scenario? Maybe it shouldn't be by design, but the Retool iFrame component will not load the Metabase content without CORS headers in place
                              2. in edge cases like this, would the ability to customize nginx headers in Cloudron user.conf solve the issue?

                              Thanks

                              girishG Offline
                              girishG Offline
                              girish
                              Staff
                              wrote on last edited by
                              #13

                              @staypath whooops sorry, that was an unintentionaly typo. I meant metabase all along. As for retool, I am just looking at what that is.

                              1 Reply Last reply
                              0
                              • girishG Offline
                                girishG Offline
                                girish
                                Staff
                                wrote on last edited by
                                #14

                                A simple iframe test works for me in Surfer:

                                    <!DOCTYPE html>    
                                    <html>    
                                    <body>    
                                    <h2>HTML Iframes example</h2>    
                                    <p>Use the height and width attributes to specify the size of the iframe:</p>    
                                    <iframe src="https://metabase.smartserver.io/public/dashboard/5124c74d-ab16-42d7-b1a1-68b774e5dd66" height="500" width="500"></iframe>    
                                    </body>    
                                    </html>  
                                

                                image.png

                                Not sure what retool is doing.

                                1 Reply Last reply
                                0
                                • girishG Offline
                                  girishG Offline
                                  girish
                                  Staff
                                  wrote on last edited by
                                  #15

                                  OK, found the problem . @staypath retool is removing the allow-same-origin from the iframe . See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#allow-same-origin . This makes API calls in the IFRAME appear as cross origin. Adding it manually in web inspector, makes retool show it:

                                  image.png

                                  1 Reply Last reply
                                  0
                                  • girishG Offline
                                    girishG Offline
                                    girish
                                    Staff
                                    wrote on last edited by
                                    #16

                                    Ah, found it. Just check this option in retool (Interaction -> Enable Storage and cookies) and it works.

                                    image.png

                                    1 Reply Last reply
                                    0
                                    • girishG girish marked this topic as a question on
                                    • girishG girish has marked this topic as solved on
                                    • S Offline
                                      S Offline
                                      staypath
                                      wrote on last edited by
                                      #17

                                      I really appreciate you looking into this. You have gone above and beyond, so thank you again. I saw the Storage and Cookies option in the Retool docs as well, and strangely, my Retool instance does not have this option. I will open a support ticket with Retool to figure out why this option is missing. Thank you again for the help with troubleshooting.
                                      CleanShot 2024-04-06 at 07.06.44@2x.png

                                      1 Reply Last reply
                                      0
                                      • girishG Offline
                                        girishG Offline
                                        girish
                                        Staff
                                        wrote on last edited by
                                        #18

                                        @staypath ah interesting. I am using the cloud version. Maybe you are on selfhosted?

                                        S 1 Reply Last reply
                                        0
                                        • girishG girish

                                          @staypath ah interesting. I am using the cloud version. Maybe you are on selfhosted?

                                          S Offline
                                          S Offline
                                          staypath
                                          wrote on last edited by
                                          #19

                                          @girish Yes, maybe that is the difference. I am using self-hosted Retool.

                                          1 Reply Last reply
                                          0
                                          • S Offline
                                            S Offline
                                            staypath
                                            wrote on last edited by
                                            #20

                                            @girish Just closing out this discussion. For reference, here is when the change was introduced to Retool that caused the issue with loading the iframe:

                                            https://docs.retool.com/releases/legacy/3.22#:~:text=Disabled Storage and cookies

                                            Thanks again.

                                            1 Reply Last reply
                                            1
                                            Reply
                                            • Reply as topic
                                            Log in to reply
                                            • Oldest to Newest
                                            • Newest to Oldest
                                            • Most Votes


                                              • Login

                                              • Don't have an account? Register

                                              • Login or register to search.
                                              • First post
                                                Last post
                                              0
                                              • Categories
                                              • Recent
                                              • Tags
                                              • Popular
                                              • Bookmarks
                                              • Search