Setup Cross-Origin Resource Sharing (CORS)

:notebook_with_decorative_cover: This is a how-to guide that will guide you through the process of setting up Cross-Origin Resource Sharing (CORS) in Discourse.

CORS is a mechanism that allows many resources (e.g., fonts, JavaScript, etc.) on a web page to be requested from another domain outside the domain from which the resource originated.

Here’s how you can set up CORS on your Discourse site:

Prerequisites

Before getting started, the DISCOURSE_ENABLE_CORS environmental variable must be set to true to enable CORS.

For assistance with this, see How to Set Environmental Variables.

:sparkles: If you are on a Discourse hosted site, this step has already been done, and you do not need to take any additional action to configure this.

Access Site Settings

Go to your Discourse admin panel. From there, navigate to the “Settings” tab.

Locate CORS Settings

In the “Settings” tab, use the search bar and type in cors origin. You should see the following setting related to CORS:

This setting allows you to specify the domains that are allowed to make cross-origin requests to your Discourse instance.

You should enter the exact domains here, separated by a space. Avoid using a wildcard (*) as this can pose security risks.

When adding multiple domains here, each URL should be separated. For example:

Save Changes

After you’ve made the necessary changes, don’t forget to click the Save Changes button at the bottom of the page.

Important Notes

Improper implementation of CORS (Cross-Origin Resource Sharing) can introduce potential security risks. Here are a few things to keep in mind when enabling CORS on your site:

  • Specify exact domains: Using wildcards (*) in the CORS configuration can allow any domain to interact with your server, which is a significant security risk. It’s recommended to specify exact domains.
  • Minimize exposed data: CORS should be set up to expose only the necessary data from external domains that you trust. Allowing sites you do not control CORS access is not recommended.
  • Use HTTPS: When possible, avoid allowing non-HTTPS sites in your CORS configuration, as this can expose data in an unencrypted format.

Last edited by @hugh 2024-05-29T06:25:46Z

Check documentPerform check on document:
2 Likes

And if Google ads are in use perhaps it is better to keep hands off from this setting :wink:

CORS (and CSP) is a bit problematic because quite often a site must allow de facto everything and then it is close to useless.

2 Likes

I have added the DISCOURSE_ENABLE_CORS: "true" to the env section of my site’s app.yml file.
I then rebuilt the app.
I then went to the cors_origins section and added the full URL of a site I’m trying to get an interaction working with and it’s still not working.
I’ve created a page to serve information when the main site is offline.
I put this js in the page to check the main site and redirect to it once it’s back up but it doesn’t seem to be working.
Here’s the code:

    <script>
        function checkSiteStatus() {
            fetch('https://discourse.technospider.com', {
                method: 'HEAD',
                mode: 'cors', // Use CORS to get status code
                cache: 'no-store' // Avoid caching
            })
            .then(response => {
                console.log('Site check: Status', response.status);
                if (response.ok) { // 200-299 status codes
                    console.log('Site is up, redirecting to Discourse');
                    window.location.replace('https://discourse.technospider.com');
                } else {
                    console.log('Site is still down (status: ' + response.status + '), retrying in 20 seconds');
                    setTimeout(checkSiteStatus, 20000);
                }
            })
            .catch(error => {
                console.log('Site check: Error (likely down or CORS issue):', error.message);
                setTimeout(checkSiteStatus, 20000);
            });
        }
            
        // Start checking immediately
        checkSiteStatus();
    </script>

And this is the console error:

[Error] Origin https://www.technospider.com is not allowed by Access-Control-Allow-Origin. Status code: 200
[Error] Fetch API cannot load https://discourse.technospider.com/ due to access control checks.
[Error] Failed to load resource: Origin https://www.technospider.com is not allowed by Access-Control-Allow-Origin. Status code: 200 (discourse.technospider.com, line 0)
[Log] Site check: Error (likely down or CORS issue): – "Load failed" (berightback, line 78)

If anyone has any insights I’d love to know about them. Grok and I are at a loss.

Try it without the double quotes, otherwise it can be interpreted as a string instead of a boolean.

Waiting for rebuild to finish now to test. If that’s the case, then someone needs to fix this page:

As it’s showing putting true inside double quotes.

Rebuild done, no change. :frowning:

Well that is odd… other environment variables there have true values with no quotes.

Is this better to use than CSP if you want to use javascript in posts for example?

I have currently relied to theme components or CSP in order to run js,

Best regards
Olle

Here it’s going into an environment variable, which can only be a string. Doesn’t matter.

But in general this is a good thing to keep in mind since you can get unexpected results for innocuous-looking values:

pry(main)> YAML.load('on: yes').to_s
=> "{true=>true}"
1 Like