How to relax Content Security Policy

Hi

I’d like to do some testing of Discourse without necessarily going through its configured public domain name. For eg if Discourse have been installed and configured as https://uat.mysite.com then I can obviously load my browser and browse to https://uat.mysite.com, which means my browser would exit my internal network out to public Internet to resolve the domain name to it’s public IP address, and load the pages via its public IP address.

I just tried browsing to Discourse via the internal IP address of the server (eg 192.168.1.2 shown below) and rightfully it doesn’t load because of Content Security Policy. The errors I’m getting are of the following form.

Refused to load the script 'http://192.168.1.2:12000/assets/locales/en-a9c88e45eb548bd7c807aecfd37d218891e213b5c1fd254857e0f16c72d73996.js' because it violates the following Content Security Policy directive: "script-src http://uat.mysite.com/logs/ http://uat.mysite.com/sidekiq/ http://uat.mysite.com/mini-profiler-resources/ http://uat.mysite.com/assets/ http://uat.mysite.com/brotli_asset/ http://uat.mysite.com/extra-locales/ http://uat.mysite.com/highlight-js/ http://uat.mysite.com/javascripts/ http://uat.mysite.com/plugins/ http://uat.mysite.com/theme-javascripts/ http://uat.mysite.com/svg-sprite/ 'sha256-rwfDVOTzygQmkOwFNAeX564B66beHoel4+gRLgQUgHg='". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
                                           ---------------------------------------------
                                          |                                             |
                                           ------------
uat.mysite.com resolves to 98.1.2.3 -->   |  Public IP |  Server running Discourse.     |
                                          |  96.1.2.3. |
                                           ------------                                 |
                                          |                                             |
                                          |                  ----------------           |
                                          |                  |  Private IP  |           |
                                          |                  | 192.168.1.2  |           |
                                           ---------------------------------------------
                                                                         ^
                                                                         |
192.168.1.2   ------------------------------------------------------------

The reason why I’d like to access Discourse via the server’s internal IP is because I want to do testing. For eg if I want to load testing I don’t necessarily want to load up the network servicing the Internet. Or if I want to install a test instance on my laptop or a build server without necessarily setting up DNS.

I guess I can always override this by setting a custom entry in /etc/hosts but is there a way to either disable CSP or set it to trust other sources to permit testing?

1 Like

Then configure your machine to resolve that address to the local ip of the discourse server. There are many ways to do that, but they are os dependent, so you should include the os in your Google search. (In Linux and I think Mac is, you can just edit /etc/hosts.)

1 Like

I actually tried /etc/hosts but still having the same error due to CSP. I’d have thought that there is a flag or setting that can be used to toggle this to enable the developers to do everything within their laptop without having to stand up a DNS solution. Looking at the Install Discourse on macOS for development - documentation / developers - Discourse Meta it appears to bootstrap into something that works with http://localhost:3000 rather than an IP.

The challenge I have is I have automation to install Discourse and want to use the same process to stand up both development, UAT, and production environments and I don’t necessarily want to have the development environment accessible from the public Internet, which appears to be a requirement atm because it needs to resolve a proper FQDN. There are multiple use cases one of which is for eg automating the upgrade of Discourse in development environment every week and run a number of tests to see if anything breaks.

Anyway if there is a way of relaxing the requirement to allow direct access via IP it’d be good to know. Otherwise I guess the only other solution is to get a small DNS service going and then point the laptop to use the custom DNS service but it seems to be a bit of a hassle.

There is a site setting named content security policy. You can uncheck and save to disable CSP.

As long as this is not done in production instance it’s okay.

3 Likes

That’s not a good idea. It will never work. A development environment is necessity different as it has assets precompiled and a bunch of other stuff that makes development impossible. Unless you are developing plugins you don’t need a development environment at all. So if that’s the case then you can have your development environment be a docker install, it’s just not what would be called a development environment here.

You want to launch your staging and production environments using docker as described in the standard install.

3 Likes

Hi! I regularly do this, but with Docker installs. Assuming that you use our standard Docker installation in production, then for your acceptance testing you should be using the same thing. There is a wide margin for differences between dev and Docker installations (configuration, gem and JS package versions, etc) that can turn into migraines at deploy time.

Docker installations use and enforce HTTPS by default. Unless you want to customize the container template (which I’ve found has some hidden complexity), you can simply turn off HTTPS enforcing with another site setting.

This is my snippet for “relaxing security in a local Docker install”, which can just as easily be reverted before going to production:

SiteSetting.content_security_policy = false
SiteSetting.force_https = false

Then it’s just a matter of your browser being able to find port 80 on the Docker container at http://uat.mysite.com – note that you’ll be using http instead of https.

For that, @pfaffman’s /etc/hosts trick is the way; details for each OS here.

2 Likes